ActivityManagerService.java revision 9693d9534342c9785877a9f98ec5aff6fd9ac496
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 = 300*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    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
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     * Current configuration information.  HistoryRecord objects are given
826     * a reference to this object to indicate which configuration they are
827     * currently running in, so this object must be kept immutable.
828     */
829    Configuration mConfiguration = new Configuration();
830
831    /**
832     * Current sequencing integer of the configuration, for skipping old
833     * configurations.
834     */
835    int mConfigurationSeq = 0;
836
837    /**
838     * Hardware-reported OpenGLES version.
839     */
840    final int GL_ES_VERSION;
841
842    /**
843     * List of initialization arguments to pass to all processes when binding applications to them.
844     * For example, references to the commonly used services.
845     */
846    HashMap<String, IBinder> mAppBindArgs;
847
848    /**
849     * Temporary to avoid allocations.  Protected by main lock.
850     */
851    final StringBuilder mStringBuilder = new StringBuilder(256);
852
853    /**
854     * Used to control how we initialize the service.
855     */
856    ComponentName mTopComponent;
857    String mTopAction = Intent.ACTION_MAIN;
858    String mTopData;
859    boolean mProcessesReady = false;
860    boolean mSystemReady = false;
861    boolean mBooting = false;
862    boolean mWaitingUpdate = false;
863    boolean mDidUpdate = false;
864    boolean mOnBattery = false;
865    boolean mLaunchWarningShown = false;
866
867    Context mContext;
868
869    int mFactoryTest;
870
871    boolean mCheckedForSetup;
872
873    /**
874     * The time at which we will allow normal application switches again,
875     * after a call to {@link #stopAppSwitches()}.
876     */
877    long mAppSwitchesAllowedTime;
878
879    /**
880     * This is set to true after the first switch after mAppSwitchesAllowedTime
881     * is set; any switches after that will clear the time.
882     */
883    boolean mDidAppSwitch;
884
885    /**
886     * Last time (in realtime) at which we checked for power usage.
887     */
888    long mLastPowerCheckRealtime;
889
890    /**
891     * Last time (in uptime) at which we checked for power usage.
892     */
893    long mLastPowerCheckUptime;
894
895    /**
896     * Set while we are wanting to sleep, to prevent any
897     * activities from being started/resumed.
898     */
899    private boolean mSleeping = false;
900
901    /**
902     * Set while we are running a voice interaction.  This overrides
903     * sleeping while it is active.
904     */
905    private boolean mRunningVoice = false;
906
907    /**
908     * State of external calls telling us if the device is asleep.
909     */
910    private boolean mWentToSleep = false;
911
912    /**
913     * State of external call telling us if the lock screen is shown.
914     */
915    private boolean mLockScreenShown = false;
916
917    /**
918     * Set if we are shutting down the system, similar to sleeping.
919     */
920    boolean mShuttingDown = false;
921
922    /**
923     * Current sequence id for oom_adj computation traversal.
924     */
925    int mAdjSeq = 0;
926
927    /**
928     * Current sequence id for process LRU updating.
929     */
930    int mLruSeq = 0;
931
932    /**
933     * Keep track of the non-cached/empty process we last found, to help
934     * determine how to distribute cached/empty processes next time.
935     */
936    int mNumNonCachedProcs = 0;
937
938    /**
939     * Keep track of the number of cached hidden procs, to balance oom adj
940     * distribution between those and empty procs.
941     */
942    int mNumCachedHiddenProcs = 0;
943
944    /**
945     * Keep track of the number of service processes we last found, to
946     * determine on the next iteration which should be B services.
947     */
948    int mNumServiceProcs = 0;
949    int mNewNumAServiceProcs = 0;
950    int mNewNumServiceProcs = 0;
951
952    /**
953     * Allow the current computed overall memory level of the system to go down?
954     * This is set to false when we are killing processes for reasons other than
955     * memory management, so that the now smaller process list will not be taken as
956     * an indication that memory is tighter.
957     */
958    boolean mAllowLowerMemLevel = false;
959
960    /**
961     * The last computed memory level, for holding when we are in a state that
962     * processes are going away for other reasons.
963     */
964    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
965
966    /**
967     * The last total number of process we have, to determine if changes actually look
968     * like a shrinking number of process due to lower RAM.
969     */
970    int mLastNumProcesses;
971
972    /**
973     * The uptime of the last time we performed idle maintenance.
974     */
975    long mLastIdleTime = SystemClock.uptimeMillis();
976
977    /**
978     * Total time spent with RAM that has been added in the past since the last idle time.
979     */
980    long mLowRamTimeSinceLastIdle = 0;
981
982    /**
983     * If RAM is currently low, when that horrible situation started.
984     */
985    long mLowRamStartTime = 0;
986
987    /**
988     * For reporting to battery stats the current top application.
989     */
990    private String mCurResumedPackage = null;
991    private int mCurResumedUid = -1;
992
993    /**
994     * For reporting to battery stats the apps currently running foreground
995     * service.  The ProcessMap is package/uid tuples; each of these contain
996     * an array of the currently foreground processes.
997     */
998    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
999            = new ProcessMap<ArrayList<ProcessRecord>>();
1000
1001    /**
1002     * This is set if we had to do a delayed dexopt of an app before launching
1003     * it, to increase the ANR timeouts in that case.
1004     */
1005    boolean mDidDexOpt;
1006
1007    /**
1008     * Set if the systemServer made a call to enterSafeMode.
1009     */
1010    boolean mSafeMode;
1011
1012    String mDebugApp = null;
1013    boolean mWaitForDebugger = false;
1014    boolean mDebugTransient = false;
1015    String mOrigDebugApp = null;
1016    boolean mOrigWaitForDebugger = false;
1017    boolean mAlwaysFinishActivities = false;
1018    IActivityController mController = null;
1019    String mProfileApp = null;
1020    ProcessRecord mProfileProc = null;
1021    String mProfileFile;
1022    ParcelFileDescriptor mProfileFd;
1023    int mProfileType = 0;
1024    boolean mAutoStopProfiler = false;
1025    String mOpenGlTraceApp = null;
1026
1027    static class ProcessChangeItem {
1028        static final int CHANGE_ACTIVITIES = 1<<0;
1029        static final int CHANGE_PROCESS_STATE = 1<<1;
1030        int changes;
1031        int uid;
1032        int pid;
1033        int processState;
1034        boolean foregroundActivities;
1035    }
1036
1037    final RemoteCallbackList<IProcessObserver> mProcessObservers
1038            = new RemoteCallbackList<IProcessObserver>();
1039    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1040
1041    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1042            = new ArrayList<ProcessChangeItem>();
1043    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1044            = new ArrayList<ProcessChangeItem>();
1045
1046    /**
1047     * Runtime CPU use collection thread.  This object's lock is used to
1048     * protect all related state.
1049     */
1050    final Thread mProcessCpuThread;
1051
1052    /**
1053     * Used to collect process stats when showing not responding dialog.
1054     * Protected by mProcessCpuThread.
1055     */
1056    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1057            MONITOR_THREAD_CPU_USAGE);
1058    final AtomicLong mLastCpuTime = new AtomicLong(0);
1059    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1060
1061    long mLastWriteTime = 0;
1062
1063    /**
1064     * Used to retain an update lock when the foreground activity is in
1065     * immersive mode.
1066     */
1067    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1068
1069    /**
1070     * Set to true after the system has finished booting.
1071     */
1072    boolean mBooted = false;
1073
1074    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1075    int mProcessLimitOverride = -1;
1076
1077    WindowManagerService mWindowManager;
1078
1079    final ActivityThread mSystemThread;
1080
1081    int mCurrentUserId = 0;
1082    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1083    private UserManagerService mUserManager;
1084
1085    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1086        final ProcessRecord mApp;
1087        final int mPid;
1088        final IApplicationThread mAppThread;
1089
1090        AppDeathRecipient(ProcessRecord app, int pid,
1091                IApplicationThread thread) {
1092            if (localLOGV) Slog.v(
1093                TAG, "New death recipient " + this
1094                + " for thread " + thread.asBinder());
1095            mApp = app;
1096            mPid = pid;
1097            mAppThread = thread;
1098        }
1099
1100        @Override
1101        public void binderDied() {
1102            if (localLOGV) Slog.v(
1103                TAG, "Death received in " + this
1104                + " for thread " + mAppThread.asBinder());
1105            synchronized(ActivityManagerService.this) {
1106                appDiedLocked(mApp, mPid, mAppThread);
1107            }
1108        }
1109    }
1110
1111    static final int SHOW_ERROR_MSG = 1;
1112    static final int SHOW_NOT_RESPONDING_MSG = 2;
1113    static final int SHOW_FACTORY_ERROR_MSG = 3;
1114    static final int UPDATE_CONFIGURATION_MSG = 4;
1115    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1116    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1117    static final int SERVICE_TIMEOUT_MSG = 12;
1118    static final int UPDATE_TIME_ZONE = 13;
1119    static final int SHOW_UID_ERROR_MSG = 14;
1120    static final int IM_FEELING_LUCKY_MSG = 15;
1121    static final int PROC_START_TIMEOUT_MSG = 20;
1122    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1123    static final int KILL_APPLICATION_MSG = 22;
1124    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1125    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1126    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1127    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1128    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1129    static final int CLEAR_DNS_CACHE_MSG = 28;
1130    static final int UPDATE_HTTP_PROXY_MSG = 29;
1131    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1132    static final int DISPATCH_PROCESSES_CHANGED = 31;
1133    static final int DISPATCH_PROCESS_DIED = 32;
1134    static final int REPORT_MEM_USAGE_MSG = 33;
1135    static final int REPORT_USER_SWITCH_MSG = 34;
1136    static final int CONTINUE_USER_SWITCH_MSG = 35;
1137    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1138    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1139    static final int PERSIST_URI_GRANTS_MSG = 38;
1140    static final int REQUEST_ALL_PSS_MSG = 39;
1141    static final int START_PROFILES_MSG = 40;
1142    static final int UPDATE_TIME = 41;
1143    static final int SYSTEM_USER_START_MSG = 42;
1144    static final int SYSTEM_USER_CURRENT_MSG = 43;
1145
1146    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1147    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1148    static final int FIRST_COMPAT_MODE_MSG = 300;
1149    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1150
1151    AlertDialog mUidAlert;
1152    CompatModeDialog mCompatModeDialog;
1153    long mLastMemUsageReportTime = 0;
1154
1155    /**
1156     * Flag whether the current user is a "monkey", i.e. whether
1157     * the UI is driven by a UI automation tool.
1158     */
1159    private boolean mUserIsMonkey;
1160
1161    final ServiceThread mHandlerThread;
1162    final MainHandler mHandler;
1163
1164    final class MainHandler extends Handler {
1165        public MainHandler(Looper looper) {
1166            super(looper, null, true);
1167        }
1168
1169        @Override
1170        public void handleMessage(Message msg) {
1171            switch (msg.what) {
1172            case SHOW_ERROR_MSG: {
1173                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1174                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1175                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1176                synchronized (ActivityManagerService.this) {
1177                    ProcessRecord proc = (ProcessRecord)data.get("app");
1178                    AppErrorResult res = (AppErrorResult) data.get("result");
1179                    if (proc != null && proc.crashDialog != null) {
1180                        Slog.e(TAG, "App already has crash dialog: " + proc);
1181                        if (res != null) {
1182                            res.set(0);
1183                        }
1184                        return;
1185                    }
1186                    if (!showBackground && UserHandle.getAppId(proc.uid)
1187                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1188                            && proc.pid != MY_PID) {
1189                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1190                        if (res != null) {
1191                            res.set(0);
1192                        }
1193                        return;
1194                    }
1195                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1196                        Dialog d = new AppErrorDialog(mContext,
1197                                ActivityManagerService.this, res, proc);
1198                        d.show();
1199                        proc.crashDialog = d;
1200                    } else {
1201                        // The device is asleep, so just pretend that the user
1202                        // saw a crash dialog and hit "force quit".
1203                        if (res != null) {
1204                            res.set(0);
1205                        }
1206                    }
1207                }
1208
1209                ensureBootCompleted();
1210            } break;
1211            case SHOW_NOT_RESPONDING_MSG: {
1212                synchronized (ActivityManagerService.this) {
1213                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1214                    ProcessRecord proc = (ProcessRecord)data.get("app");
1215                    if (proc != null && proc.anrDialog != null) {
1216                        Slog.e(TAG, "App already has anr dialog: " + proc);
1217                        return;
1218                    }
1219
1220                    Intent intent = new Intent("android.intent.action.ANR");
1221                    if (!mProcessesReady) {
1222                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1223                                | Intent.FLAG_RECEIVER_FOREGROUND);
1224                    }
1225                    broadcastIntentLocked(null, null, intent,
1226                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1227                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1228
1229                    if (mShowDialogs) {
1230                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1231                                mContext, proc, (ActivityRecord)data.get("activity"),
1232                                msg.arg1 != 0);
1233                        d.show();
1234                        proc.anrDialog = d;
1235                    } else {
1236                        // Just kill the app if there is no dialog to be shown.
1237                        killAppAtUsersRequest(proc, null);
1238                    }
1239                }
1240
1241                ensureBootCompleted();
1242            } break;
1243            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                synchronized (ActivityManagerService.this) {
1246                    ProcessRecord proc = (ProcessRecord) data.get("app");
1247                    if (proc == null) {
1248                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1249                        break;
1250                    }
1251                    if (proc.crashDialog != null) {
1252                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1253                        return;
1254                    }
1255                    AppErrorResult res = (AppErrorResult) data.get("result");
1256                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1257                        Dialog d = new StrictModeViolationDialog(mContext,
1258                                ActivityManagerService.this, res, proc);
1259                        d.show();
1260                        proc.crashDialog = d;
1261                    } else {
1262                        // The device is asleep, so just pretend that the user
1263                        // saw a crash dialog and hit "force quit".
1264                        res.set(0);
1265                    }
1266                }
1267                ensureBootCompleted();
1268            } break;
1269            case SHOW_FACTORY_ERROR_MSG: {
1270                Dialog d = new FactoryErrorDialog(
1271                    mContext, msg.getData().getCharSequence("msg"));
1272                d.show();
1273                ensureBootCompleted();
1274            } break;
1275            case UPDATE_CONFIGURATION_MSG: {
1276                final ContentResolver resolver = mContext.getContentResolver();
1277                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1278            } break;
1279            case GC_BACKGROUND_PROCESSES_MSG: {
1280                synchronized (ActivityManagerService.this) {
1281                    performAppGcsIfAppropriateLocked();
1282                }
1283            } break;
1284            case WAIT_FOR_DEBUGGER_MSG: {
1285                synchronized (ActivityManagerService.this) {
1286                    ProcessRecord app = (ProcessRecord)msg.obj;
1287                    if (msg.arg1 != 0) {
1288                        if (!app.waitedForDebugger) {
1289                            Dialog d = new AppWaitingForDebuggerDialog(
1290                                    ActivityManagerService.this,
1291                                    mContext, app);
1292                            app.waitDialog = d;
1293                            app.waitedForDebugger = true;
1294                            d.show();
1295                        }
1296                    } else {
1297                        if (app.waitDialog != null) {
1298                            app.waitDialog.dismiss();
1299                            app.waitDialog = null;
1300                        }
1301                    }
1302                }
1303            } break;
1304            case SERVICE_TIMEOUT_MSG: {
1305                if (mDidDexOpt) {
1306                    mDidDexOpt = false;
1307                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1308                    nmsg.obj = msg.obj;
1309                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1310                    return;
1311                }
1312                mServices.serviceTimeout((ProcessRecord)msg.obj);
1313            } break;
1314            case UPDATE_TIME_ZONE: {
1315                synchronized (ActivityManagerService.this) {
1316                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1317                        ProcessRecord r = mLruProcesses.get(i);
1318                        if (r.thread != null) {
1319                            try {
1320                                r.thread.updateTimeZone();
1321                            } catch (RemoteException ex) {
1322                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1323                            }
1324                        }
1325                    }
1326                }
1327            } break;
1328            case CLEAR_DNS_CACHE_MSG: {
1329                synchronized (ActivityManagerService.this) {
1330                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1331                        ProcessRecord r = mLruProcesses.get(i);
1332                        if (r.thread != null) {
1333                            try {
1334                                r.thread.clearDnsCache();
1335                            } catch (RemoteException ex) {
1336                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1337                            }
1338                        }
1339                    }
1340                }
1341            } break;
1342            case UPDATE_HTTP_PROXY_MSG: {
1343                ProxyInfo proxy = (ProxyInfo)msg.obj;
1344                String host = "";
1345                String port = "";
1346                String exclList = "";
1347                Uri pacFileUrl = Uri.EMPTY;
1348                if (proxy != null) {
1349                    host = proxy.getHost();
1350                    port = Integer.toString(proxy.getPort());
1351                    exclList = proxy.getExclusionListAsString();
1352                    pacFileUrl = proxy.getPacFileUrl();
1353                }
1354                synchronized (ActivityManagerService.this) {
1355                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1356                        ProcessRecord r = mLruProcesses.get(i);
1357                        if (r.thread != null) {
1358                            try {
1359                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1360                            } catch (RemoteException ex) {
1361                                Slog.w(TAG, "Failed to update http proxy for: " +
1362                                        r.info.processName);
1363                            }
1364                        }
1365                    }
1366                }
1367            } break;
1368            case SHOW_UID_ERROR_MSG: {
1369                String title = "System UIDs Inconsistent";
1370                String text = "UIDs on the system are inconsistent, you need to wipe your"
1371                        + " data partition or your device will be unstable.";
1372                Log.e(TAG, title + ": " + text);
1373                if (mShowDialogs) {
1374                    // XXX This is a temporary dialog, no need to localize.
1375                    AlertDialog d = new BaseErrorDialog(mContext);
1376                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1377                    d.setCancelable(false);
1378                    d.setTitle(title);
1379                    d.setMessage(text);
1380                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1381                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1382                    mUidAlert = d;
1383                    d.show();
1384                }
1385            } break;
1386            case IM_FEELING_LUCKY_MSG: {
1387                if (mUidAlert != null) {
1388                    mUidAlert.dismiss();
1389                    mUidAlert = null;
1390                }
1391            } break;
1392            case PROC_START_TIMEOUT_MSG: {
1393                if (mDidDexOpt) {
1394                    mDidDexOpt = false;
1395                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1396                    nmsg.obj = msg.obj;
1397                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1398                    return;
1399                }
1400                ProcessRecord app = (ProcessRecord)msg.obj;
1401                synchronized (ActivityManagerService.this) {
1402                    processStartTimedOutLocked(app);
1403                }
1404            } break;
1405            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1406                synchronized (ActivityManagerService.this) {
1407                    doPendingActivityLaunchesLocked(true);
1408                }
1409            } break;
1410            case KILL_APPLICATION_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    int appid = msg.arg1;
1413                    boolean restart = (msg.arg2 == 1);
1414                    Bundle bundle = (Bundle)msg.obj;
1415                    String pkg = bundle.getString("pkg");
1416                    String reason = bundle.getString("reason");
1417                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1418                            false, UserHandle.USER_ALL, reason);
1419                }
1420            } break;
1421            case FINALIZE_PENDING_INTENT_MSG: {
1422                ((PendingIntentRecord)msg.obj).completeFinalize();
1423            } break;
1424            case POST_HEAVY_NOTIFICATION_MSG: {
1425                INotificationManager inm = NotificationManager.getService();
1426                if (inm == null) {
1427                    return;
1428                }
1429
1430                ActivityRecord root = (ActivityRecord)msg.obj;
1431                ProcessRecord process = root.app;
1432                if (process == null) {
1433                    return;
1434                }
1435
1436                try {
1437                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1438                    String text = mContext.getString(R.string.heavy_weight_notification,
1439                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1440                    Notification notification = new Notification();
1441                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1442                    notification.when = 0;
1443                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1444                    notification.tickerText = text;
1445                    notification.defaults = 0; // please be quiet
1446                    notification.sound = null;
1447                    notification.vibrate = null;
1448                    notification.setLatestEventInfo(context, text,
1449                            mContext.getText(R.string.heavy_weight_notification_detail),
1450                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1451                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1452                                    new UserHandle(root.userId)));
1453
1454                    try {
1455                        int[] outId = new int[1];
1456                        inm.enqueueNotificationWithTag("android", "android", null,
1457                                R.string.heavy_weight_notification,
1458                                notification, outId, root.userId);
1459                    } catch (RuntimeException e) {
1460                        Slog.w(ActivityManagerService.TAG,
1461                                "Error showing notification for heavy-weight app", e);
1462                    } catch (RemoteException e) {
1463                    }
1464                } catch (NameNotFoundException e) {
1465                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1466                }
1467            } break;
1468            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1469                INotificationManager inm = NotificationManager.getService();
1470                if (inm == null) {
1471                    return;
1472                }
1473                try {
1474                    inm.cancelNotificationWithTag("android", null,
1475                            R.string.heavy_weight_notification,  msg.arg1);
1476                } catch (RuntimeException e) {
1477                    Slog.w(ActivityManagerService.TAG,
1478                            "Error canceling notification for service", e);
1479                } catch (RemoteException e) {
1480                }
1481            } break;
1482            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1483                synchronized (ActivityManagerService.this) {
1484                    checkExcessivePowerUsageLocked(true);
1485                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1486                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1487                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1488                }
1489            } break;
1490            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1491                synchronized (ActivityManagerService.this) {
1492                    ActivityRecord ar = (ActivityRecord)msg.obj;
1493                    if (mCompatModeDialog != null) {
1494                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1495                                ar.info.applicationInfo.packageName)) {
1496                            return;
1497                        }
1498                        mCompatModeDialog.dismiss();
1499                        mCompatModeDialog = null;
1500                    }
1501                    if (ar != null && false) {
1502                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1503                                ar.packageName)) {
1504                            int mode = mCompatModePackages.computeCompatModeLocked(
1505                                    ar.info.applicationInfo);
1506                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1507                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1508                                mCompatModeDialog = new CompatModeDialog(
1509                                        ActivityManagerService.this, mContext,
1510                                        ar.info.applicationInfo);
1511                                mCompatModeDialog.show();
1512                            }
1513                        }
1514                    }
1515                }
1516                break;
1517            }
1518            case DISPATCH_PROCESSES_CHANGED: {
1519                dispatchProcessesChanged();
1520                break;
1521            }
1522            case DISPATCH_PROCESS_DIED: {
1523                final int pid = msg.arg1;
1524                final int uid = msg.arg2;
1525                dispatchProcessDied(pid, uid);
1526                break;
1527            }
1528            case REPORT_MEM_USAGE_MSG: {
1529                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1530                Thread thread = new Thread() {
1531                    @Override public void run() {
1532                        final SparseArray<ProcessMemInfo> infoMap
1533                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1534                        for (int i=0, N=memInfos.size(); i<N; i++) {
1535                            ProcessMemInfo mi = memInfos.get(i);
1536                            infoMap.put(mi.pid, mi);
1537                        }
1538                        updateCpuStatsNow();
1539                        synchronized (mProcessCpuThread) {
1540                            final int N = mProcessCpuTracker.countStats();
1541                            for (int i=0; i<N; i++) {
1542                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1543                                if (st.vsize > 0) {
1544                                    long pss = Debug.getPss(st.pid, null);
1545                                    if (pss > 0) {
1546                                        if (infoMap.indexOfKey(st.pid) < 0) {
1547                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1548                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1549                                            mi.pss = pss;
1550                                            memInfos.add(mi);
1551                                        }
1552                                    }
1553                                }
1554                            }
1555                        }
1556
1557                        long totalPss = 0;
1558                        for (int i=0, N=memInfos.size(); i<N; i++) {
1559                            ProcessMemInfo mi = memInfos.get(i);
1560                            if (mi.pss == 0) {
1561                                mi.pss = Debug.getPss(mi.pid, null);
1562                            }
1563                            totalPss += mi.pss;
1564                        }
1565                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1566                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1567                                if (lhs.oomAdj != rhs.oomAdj) {
1568                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1569                                }
1570                                if (lhs.pss != rhs.pss) {
1571                                    return lhs.pss < rhs.pss ? 1 : -1;
1572                                }
1573                                return 0;
1574                            }
1575                        });
1576
1577                        StringBuilder tag = new StringBuilder(128);
1578                        StringBuilder stack = new StringBuilder(128);
1579                        tag.append("Low on memory -- ");
1580                        appendMemBucket(tag, totalPss, "total", false);
1581                        appendMemBucket(stack, totalPss, "total", true);
1582
1583                        StringBuilder logBuilder = new StringBuilder(1024);
1584                        logBuilder.append("Low on memory:\n");
1585
1586                        boolean firstLine = true;
1587                        int lastOomAdj = Integer.MIN_VALUE;
1588                        for (int i=0, N=memInfos.size(); i<N; i++) {
1589                            ProcessMemInfo mi = memInfos.get(i);
1590
1591                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1592                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1593                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1594                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1595                                if (lastOomAdj != mi.oomAdj) {
1596                                    lastOomAdj = mi.oomAdj;
1597                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1598                                        tag.append(" / ");
1599                                    }
1600                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1601                                        if (firstLine) {
1602                                            stack.append(":");
1603                                            firstLine = false;
1604                                        }
1605                                        stack.append("\n\t at ");
1606                                    } else {
1607                                        stack.append("$");
1608                                    }
1609                                } else {
1610                                    tag.append(" ");
1611                                    stack.append("$");
1612                                }
1613                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1614                                    appendMemBucket(tag, mi.pss, mi.name, false);
1615                                }
1616                                appendMemBucket(stack, mi.pss, mi.name, true);
1617                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1618                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1619                                    stack.append("(");
1620                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1621                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1622                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1623                                            stack.append(":");
1624                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1625                                        }
1626                                    }
1627                                    stack.append(")");
1628                                }
1629                            }
1630
1631                            logBuilder.append("  ");
1632                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1633                            logBuilder.append(' ');
1634                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1635                            logBuilder.append(' ');
1636                            ProcessList.appendRamKb(logBuilder, mi.pss);
1637                            logBuilder.append(" kB: ");
1638                            logBuilder.append(mi.name);
1639                            logBuilder.append(" (");
1640                            logBuilder.append(mi.pid);
1641                            logBuilder.append(") ");
1642                            logBuilder.append(mi.adjType);
1643                            logBuilder.append('\n');
1644                            if (mi.adjReason != null) {
1645                                logBuilder.append("                      ");
1646                                logBuilder.append(mi.adjReason);
1647                                logBuilder.append('\n');
1648                            }
1649                        }
1650
1651                        logBuilder.append("           ");
1652                        ProcessList.appendRamKb(logBuilder, totalPss);
1653                        logBuilder.append(" kB: TOTAL\n");
1654
1655                        long[] infos = new long[Debug.MEMINFO_COUNT];
1656                        Debug.getMemInfo(infos);
1657                        logBuilder.append("  MemInfo: ");
1658                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1659                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1660                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1661                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1662                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1663                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1664                            logBuilder.append("  ZRAM: ");
1665                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1666                            logBuilder.append(" kB RAM, ");
1667                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1668                            logBuilder.append(" kB swap total, ");
1669                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1670                            logBuilder.append(" kB swap free\n");
1671                        }
1672                        Slog.i(TAG, logBuilder.toString());
1673
1674                        StringBuilder dropBuilder = new StringBuilder(1024);
1675                        /*
1676                        StringWriter oomSw = new StringWriter();
1677                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1678                        StringWriter catSw = new StringWriter();
1679                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1680                        String[] emptyArgs = new String[] { };
1681                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1682                        oomPw.flush();
1683                        String oomString = oomSw.toString();
1684                        */
1685                        dropBuilder.append(stack);
1686                        dropBuilder.append('\n');
1687                        dropBuilder.append('\n');
1688                        dropBuilder.append(logBuilder);
1689                        dropBuilder.append('\n');
1690                        /*
1691                        dropBuilder.append(oomString);
1692                        dropBuilder.append('\n');
1693                        */
1694                        StringWriter catSw = new StringWriter();
1695                        synchronized (ActivityManagerService.this) {
1696                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1697                            String[] emptyArgs = new String[] { };
1698                            catPw.println();
1699                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1700                            catPw.println();
1701                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1702                                    false, false, null);
1703                            catPw.println();
1704                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1705                            catPw.flush();
1706                        }
1707                        dropBuilder.append(catSw.toString());
1708                        addErrorToDropBox("lowmem", null, "system_server", null,
1709                                null, tag.toString(), dropBuilder.toString(), null, null);
1710                        //Slog.i(TAG, "Sent to dropbox:");
1711                        //Slog.i(TAG, dropBuilder.toString());
1712                        synchronized (ActivityManagerService.this) {
1713                            long now = SystemClock.uptimeMillis();
1714                            if (mLastMemUsageReportTime < now) {
1715                                mLastMemUsageReportTime = now;
1716                            }
1717                        }
1718                    }
1719                };
1720                thread.start();
1721                break;
1722            }
1723            case REPORT_USER_SWITCH_MSG: {
1724                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1725                break;
1726            }
1727            case CONTINUE_USER_SWITCH_MSG: {
1728                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1729                break;
1730            }
1731            case USER_SWITCH_TIMEOUT_MSG: {
1732                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1733                break;
1734            }
1735            case IMMERSIVE_MODE_LOCK_MSG: {
1736                final boolean nextState = (msg.arg1 != 0);
1737                if (mUpdateLock.isHeld() != nextState) {
1738                    if (DEBUG_IMMERSIVE) {
1739                        final ActivityRecord r = (ActivityRecord) msg.obj;
1740                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1741                    }
1742                    if (nextState) {
1743                        mUpdateLock.acquire();
1744                    } else {
1745                        mUpdateLock.release();
1746                    }
1747                }
1748                break;
1749            }
1750            case PERSIST_URI_GRANTS_MSG: {
1751                writeGrantedUriPermissions();
1752                break;
1753            }
1754            case REQUEST_ALL_PSS_MSG: {
1755                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1756                break;
1757            }
1758            case START_PROFILES_MSG: {
1759                synchronized (ActivityManagerService.this) {
1760                    startProfilesLocked();
1761                }
1762                break;
1763            }
1764            case UPDATE_TIME: {
1765                synchronized (ActivityManagerService.this) {
1766                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767                        ProcessRecord r = mLruProcesses.get(i);
1768                        if (r.thread != null) {
1769                            try {
1770                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1771                            } catch (RemoteException ex) {
1772                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1773                            }
1774                        }
1775                    }
1776                }
1777                break;
1778            }
1779            case SYSTEM_USER_START_MSG: {
1780                mSystemServiceManager.startUser(msg.arg1);
1781                break;
1782            }
1783            case SYSTEM_USER_CURRENT_MSG: {
1784                mSystemServiceManager.switchUser(msg.arg1);
1785                break;
1786            }
1787            }
1788        }
1789    };
1790
1791    static final int COLLECT_PSS_BG_MSG = 1;
1792
1793    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1794        @Override
1795        public void handleMessage(Message msg) {
1796            switch (msg.what) {
1797            case COLLECT_PSS_BG_MSG: {
1798                int i=0, num=0;
1799                long start = SystemClock.uptimeMillis();
1800                long[] tmp = new long[1];
1801                do {
1802                    ProcessRecord proc;
1803                    int procState;
1804                    int pid;
1805                    synchronized (ActivityManagerService.this) {
1806                        if (i >= mPendingPssProcesses.size()) {
1807                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1808                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1809                            mPendingPssProcesses.clear();
1810                            return;
1811                        }
1812                        proc = mPendingPssProcesses.get(i);
1813                        procState = proc.pssProcState;
1814                        if (proc.thread != null && procState == proc.setProcState) {
1815                            pid = proc.pid;
1816                        } else {
1817                            proc = null;
1818                            pid = 0;
1819                        }
1820                        i++;
1821                    }
1822                    if (proc != null) {
1823                        long pss = Debug.getPss(pid, tmp);
1824                        synchronized (ActivityManagerService.this) {
1825                            if (proc.thread != null && proc.setProcState == procState
1826                                    && proc.pid == pid) {
1827                                num++;
1828                                proc.lastPssTime = SystemClock.uptimeMillis();
1829                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1830                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1831                                        + ": " + pss + " lastPss=" + proc.lastPss
1832                                        + " state=" + ProcessList.makeProcStateString(procState));
1833                                if (proc.initialIdlePss == 0) {
1834                                    proc.initialIdlePss = pss;
1835                                }
1836                                proc.lastPss = pss;
1837                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1838                                    proc.lastCachedPss = pss;
1839                                }
1840                            }
1841                        }
1842                    }
1843                } while (true);
1844            }
1845            }
1846        }
1847    };
1848
1849    /**
1850     * Monitor for package changes and update our internal state.
1851     */
1852    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1853        @Override
1854        public void onPackageRemoved(String packageName, int uid) {
1855            // Remove all tasks with activities in the specified package from the list of recent tasks
1856            synchronized (ActivityManagerService.this) {
1857                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1858                    TaskRecord tr = mRecentTasks.get(i);
1859                    ComponentName cn = tr.intent.getComponent();
1860                    if (cn != null && cn.getPackageName().equals(packageName)) {
1861                        // If the package name matches, remove the task and kill the process
1862                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1863                    }
1864                }
1865            }
1866        }
1867
1868        @Override
1869        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1870            onPackageModified(packageName);
1871            return true;
1872        }
1873
1874        @Override
1875        public void onPackageModified(String packageName) {
1876            final PackageManager pm = mContext.getPackageManager();
1877            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1878                    new ArrayList<Pair<Intent, Integer>>();
1879            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1880            // Copy the list of recent tasks so that we don't hold onto the lock on
1881            // ActivityManagerService for long periods while checking if components exist.
1882            synchronized (ActivityManagerService.this) {
1883                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1884                    TaskRecord tr = mRecentTasks.get(i);
1885                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1886                }
1887            }
1888            // Check the recent tasks and filter out all tasks with components that no longer exist.
1889            Intent tmpI = new Intent();
1890            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1891                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1892                ComponentName cn = p.first.getComponent();
1893                if (cn != null && cn.getPackageName().equals(packageName)) {
1894                    try {
1895                        // Add the task to the list to remove if the component no longer exists
1896                        tmpI.setComponent(cn);
1897                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1898                            tasksToRemove.add(p.second);
1899                        }
1900                    } catch (Exception e) {}
1901                }
1902            }
1903            // Prune all the tasks with removed components from the list of recent tasks
1904            synchronized (ActivityManagerService.this) {
1905                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1906                    // Remove the task but don't kill the process (since other components in that
1907                    // package may still be running and in the background)
1908                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1909                }
1910            }
1911        }
1912
1913        @Override
1914        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1915            // Force stop the specified packages
1916            if (packages != null) {
1917                for (String pkg : packages) {
1918                    synchronized (ActivityManagerService.this) {
1919                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1920                                "finished booting")) {
1921                            return true;
1922                        }
1923                    }
1924                }
1925            }
1926            return false;
1927        }
1928    };
1929
1930    public void setSystemProcess() {
1931        try {
1932            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1933            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1934            ServiceManager.addService("meminfo", new MemBinder(this));
1935            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1936            ServiceManager.addService("dbinfo", new DbBinder(this));
1937            if (MONITOR_CPU_USAGE) {
1938                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1939            }
1940            ServiceManager.addService("permission", new PermissionController(this));
1941
1942            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1943                    "android", STOCK_PM_FLAGS);
1944            mSystemThread.installSystemApplicationInfo(info);
1945
1946            synchronized (this) {
1947                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1948                app.persistent = true;
1949                app.pid = MY_PID;
1950                app.maxAdj = ProcessList.SYSTEM_ADJ;
1951                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1952                mProcessNames.put(app.processName, app.uid, app);
1953                synchronized (mPidsSelfLocked) {
1954                    mPidsSelfLocked.put(app.pid, app);
1955                }
1956                updateLruProcessLocked(app, false, null);
1957                updateOomAdjLocked();
1958            }
1959        } catch (PackageManager.NameNotFoundException e) {
1960            throw new RuntimeException(
1961                    "Unable to find android system package", e);
1962        }
1963    }
1964
1965    public void setWindowManager(WindowManagerService wm) {
1966        mWindowManager = wm;
1967        mStackSupervisor.setWindowManager(wm);
1968    }
1969
1970    public void startObservingNativeCrashes() {
1971        final NativeCrashListener ncl = new NativeCrashListener(this);
1972        ncl.start();
1973    }
1974
1975    public IAppOpsService getAppOpsService() {
1976        return mAppOpsService;
1977    }
1978
1979    static class MemBinder extends Binder {
1980        ActivityManagerService mActivityManagerService;
1981        MemBinder(ActivityManagerService activityManagerService) {
1982            mActivityManagerService = activityManagerService;
1983        }
1984
1985        @Override
1986        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1987            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1988                    != PackageManager.PERMISSION_GRANTED) {
1989                pw.println("Permission Denial: can't dump meminfo from from pid="
1990                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1991                        + " without permission " + android.Manifest.permission.DUMP);
1992                return;
1993            }
1994
1995            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1996        }
1997    }
1998
1999    static class GraphicsBinder extends Binder {
2000        ActivityManagerService mActivityManagerService;
2001        GraphicsBinder(ActivityManagerService activityManagerService) {
2002            mActivityManagerService = activityManagerService;
2003        }
2004
2005        @Override
2006        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2007            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2008                    != PackageManager.PERMISSION_GRANTED) {
2009                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2010                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2011                        + " without permission " + android.Manifest.permission.DUMP);
2012                return;
2013            }
2014
2015            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2016        }
2017    }
2018
2019    static class DbBinder extends Binder {
2020        ActivityManagerService mActivityManagerService;
2021        DbBinder(ActivityManagerService activityManagerService) {
2022            mActivityManagerService = activityManagerService;
2023        }
2024
2025        @Override
2026        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2027            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2028                    != PackageManager.PERMISSION_GRANTED) {
2029                pw.println("Permission Denial: can't dump dbinfo from from pid="
2030                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2031                        + " without permission " + android.Manifest.permission.DUMP);
2032                return;
2033            }
2034
2035            mActivityManagerService.dumpDbInfo(fd, pw, args);
2036        }
2037    }
2038
2039    static class CpuBinder extends Binder {
2040        ActivityManagerService mActivityManagerService;
2041        CpuBinder(ActivityManagerService activityManagerService) {
2042            mActivityManagerService = activityManagerService;
2043        }
2044
2045        @Override
2046        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2047            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2048                    != PackageManager.PERMISSION_GRANTED) {
2049                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2050                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2051                        + " without permission " + android.Manifest.permission.DUMP);
2052                return;
2053            }
2054
2055            synchronized (mActivityManagerService.mProcessCpuThread) {
2056                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2057                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2058                        SystemClock.uptimeMillis()));
2059            }
2060        }
2061    }
2062
2063    public static final class Lifecycle extends SystemService {
2064        private final ActivityManagerService mService;
2065
2066        public Lifecycle(Context context) {
2067            super(context);
2068            mService = new ActivityManagerService(context);
2069        }
2070
2071        @Override
2072        public void onStart() {
2073            mService.start();
2074        }
2075
2076        public ActivityManagerService getService() {
2077            return mService;
2078        }
2079    }
2080
2081    // Note: This method is invoked on the main thread but may need to attach various
2082    // handlers to other threads.  So take care to be explicit about the looper.
2083    public ActivityManagerService(Context systemContext) {
2084        mContext = systemContext;
2085        mFactoryTest = FactoryTest.getMode();
2086        mSystemThread = ActivityThread.currentActivityThread();
2087
2088        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2089
2090        mHandlerThread = new ServiceThread(TAG,
2091                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2092        mHandlerThread.start();
2093        mHandler = new MainHandler(mHandlerThread.getLooper());
2094
2095        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2096                "foreground", BROADCAST_FG_TIMEOUT, false);
2097        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2098                "background", BROADCAST_BG_TIMEOUT, true);
2099        mBroadcastQueues[0] = mFgBroadcastQueue;
2100        mBroadcastQueues[1] = mBgBroadcastQueue;
2101
2102        mServices = new ActiveServices(this);
2103        mProviderMap = new ProviderMap(this);
2104
2105        // TODO: Move creation of battery stats service outside of activity manager service.
2106        File dataDir = Environment.getDataDirectory();
2107        File systemDir = new File(dataDir, "system");
2108        systemDir.mkdirs();
2109        mBatteryStatsService = new BatteryStatsService(new File(
2110                systemDir, "batterystats.bin").toString(), mHandler);
2111        mBatteryStatsService.getActiveStatistics().readLocked();
2112        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2113        mOnBattery = DEBUG_POWER ? true
2114                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2115        mBatteryStatsService.getActiveStatistics().setCallback(this);
2116
2117        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2118
2119        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2120        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2121
2122        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2123
2124        // User 0 is the first and only user that runs at boot.
2125        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2126        mUserLru.add(Integer.valueOf(0));
2127        updateStartedUserArrayLocked();
2128
2129        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2130            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2131
2132        mConfiguration.setToDefaults();
2133        mConfiguration.setLocale(Locale.getDefault());
2134
2135        mConfigurationSeq = mConfiguration.seq = 1;
2136        mProcessCpuTracker.init();
2137
2138        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2139        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2140        mStackSupervisor = new ActivityStackSupervisor(this);
2141
2142        mProcessCpuThread = new Thread("CpuTracker") {
2143            @Override
2144            public void run() {
2145                while (true) {
2146                    try {
2147                        try {
2148                            synchronized(this) {
2149                                final long now = SystemClock.uptimeMillis();
2150                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2151                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2152                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2153                                //        + ", write delay=" + nextWriteDelay);
2154                                if (nextWriteDelay < nextCpuDelay) {
2155                                    nextCpuDelay = nextWriteDelay;
2156                                }
2157                                if (nextCpuDelay > 0) {
2158                                    mProcessCpuMutexFree.set(true);
2159                                    this.wait(nextCpuDelay);
2160                                }
2161                            }
2162                        } catch (InterruptedException e) {
2163                        }
2164                        updateCpuStatsNow();
2165                    } catch (Exception e) {
2166                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2167                    }
2168                }
2169            }
2170        };
2171
2172        Watchdog.getInstance().addMonitor(this);
2173        Watchdog.getInstance().addThread(mHandler);
2174    }
2175
2176    public void setSystemServiceManager(SystemServiceManager mgr) {
2177        mSystemServiceManager = mgr;
2178    }
2179
2180    private void start() {
2181        mProcessCpuThread.start();
2182
2183        mBatteryStatsService.publish(mContext);
2184        mUsageStatsService.publish(mContext);
2185        mAppOpsService.publish(mContext);
2186
2187        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2188    }
2189
2190    @Override
2191    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2192            throws RemoteException {
2193        if (code == SYSPROPS_TRANSACTION) {
2194            // We need to tell all apps about the system property change.
2195            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2196            synchronized(this) {
2197                final int NP = mProcessNames.getMap().size();
2198                for (int ip=0; ip<NP; ip++) {
2199                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2200                    final int NA = apps.size();
2201                    for (int ia=0; ia<NA; ia++) {
2202                        ProcessRecord app = apps.valueAt(ia);
2203                        if (app.thread != null) {
2204                            procs.add(app.thread.asBinder());
2205                        }
2206                    }
2207                }
2208            }
2209
2210            int N = procs.size();
2211            for (int i=0; i<N; i++) {
2212                Parcel data2 = Parcel.obtain();
2213                try {
2214                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2215                } catch (RemoteException e) {
2216                }
2217                data2.recycle();
2218            }
2219        }
2220        try {
2221            return super.onTransact(code, data, reply, flags);
2222        } catch (RuntimeException e) {
2223            // The activity manager only throws security exceptions, so let's
2224            // log all others.
2225            if (!(e instanceof SecurityException)) {
2226                Slog.wtf(TAG, "Activity Manager Crash", e);
2227            }
2228            throw e;
2229        }
2230    }
2231
2232    void updateCpuStats() {
2233        final long now = SystemClock.uptimeMillis();
2234        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2235            return;
2236        }
2237        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2238            synchronized (mProcessCpuThread) {
2239                mProcessCpuThread.notify();
2240            }
2241        }
2242    }
2243
2244    void updateCpuStatsNow() {
2245        synchronized (mProcessCpuThread) {
2246            mProcessCpuMutexFree.set(false);
2247            final long now = SystemClock.uptimeMillis();
2248            boolean haveNewCpuStats = false;
2249
2250            if (MONITOR_CPU_USAGE &&
2251                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2252                mLastCpuTime.set(now);
2253                haveNewCpuStats = true;
2254                mProcessCpuTracker.update();
2255                //Slog.i(TAG, mProcessCpu.printCurrentState());
2256                //Slog.i(TAG, "Total CPU usage: "
2257                //        + mProcessCpu.getTotalCpuPercent() + "%");
2258
2259                // Slog the cpu usage if the property is set.
2260                if ("true".equals(SystemProperties.get("events.cpu"))) {
2261                    int user = mProcessCpuTracker.getLastUserTime();
2262                    int system = mProcessCpuTracker.getLastSystemTime();
2263                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2264                    int irq = mProcessCpuTracker.getLastIrqTime();
2265                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2266                    int idle = mProcessCpuTracker.getLastIdleTime();
2267
2268                    int total = user + system + iowait + irq + softIrq + idle;
2269                    if (total == 0) total = 1;
2270
2271                    EventLog.writeEvent(EventLogTags.CPU,
2272                            ((user+system+iowait+irq+softIrq) * 100) / total,
2273                            (user * 100) / total,
2274                            (system * 100) / total,
2275                            (iowait * 100) / total,
2276                            (irq * 100) / total,
2277                            (softIrq * 100) / total);
2278                }
2279            }
2280
2281            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2282            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2283            synchronized(bstats) {
2284                synchronized(mPidsSelfLocked) {
2285                    if (haveNewCpuStats) {
2286                        if (mOnBattery) {
2287                            int perc = bstats.startAddingCpuLocked();
2288                            int totalUTime = 0;
2289                            int totalSTime = 0;
2290                            final int N = mProcessCpuTracker.countStats();
2291                            for (int i=0; i<N; i++) {
2292                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2293                                if (!st.working) {
2294                                    continue;
2295                                }
2296                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2297                                int otherUTime = (st.rel_utime*perc)/100;
2298                                int otherSTime = (st.rel_stime*perc)/100;
2299                                totalUTime += otherUTime;
2300                                totalSTime += otherSTime;
2301                                if (pr != null) {
2302                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2303                                    if (ps == null || !ps.isActive()) {
2304                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2305                                                pr.info.uid, pr.processName);
2306                                    }
2307                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2308                                            st.rel_stime-otherSTime);
2309                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2310                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2311                                } else {
2312                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2313                                    if (ps == null || !ps.isActive()) {
2314                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2315                                                bstats.mapUid(st.uid), st.name);
2316                                    }
2317                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2318                                            st.rel_stime-otherSTime);
2319                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2320                                }
2321                            }
2322                            bstats.finishAddingCpuLocked(perc, totalUTime,
2323                                    totalSTime, cpuSpeedTimes);
2324                        }
2325                    }
2326                }
2327
2328                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2329                    mLastWriteTime = now;
2330                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2331                }
2332            }
2333        }
2334    }
2335
2336    @Override
2337    public void batteryNeedsCpuUpdate() {
2338        updateCpuStatsNow();
2339    }
2340
2341    @Override
2342    public void batteryPowerChanged(boolean onBattery) {
2343        // When plugging in, update the CPU stats first before changing
2344        // the plug state.
2345        updateCpuStatsNow();
2346        synchronized (this) {
2347            synchronized(mPidsSelfLocked) {
2348                mOnBattery = DEBUG_POWER ? true : onBattery;
2349            }
2350        }
2351    }
2352
2353    /**
2354     * Initialize the application bind args. These are passed to each
2355     * process when the bindApplication() IPC is sent to the process. They're
2356     * lazily setup to make sure the services are running when they're asked for.
2357     */
2358    private HashMap<String, IBinder> getCommonServicesLocked() {
2359        if (mAppBindArgs == null) {
2360            mAppBindArgs = new HashMap<String, IBinder>();
2361
2362            // Setup the application init args
2363            mAppBindArgs.put("package", ServiceManager.getService("package"));
2364            mAppBindArgs.put("window", ServiceManager.getService("window"));
2365            mAppBindArgs.put(Context.ALARM_SERVICE,
2366                    ServiceManager.getService(Context.ALARM_SERVICE));
2367        }
2368        return mAppBindArgs;
2369    }
2370
2371    final void setFocusedActivityLocked(ActivityRecord r) {
2372        if (mFocusedActivity != r) {
2373            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2374            mFocusedActivity = r;
2375            if (r.task != null && r.task.voiceInteractor != null) {
2376                startRunningVoiceLocked();
2377            } else {
2378                finishRunningVoiceLocked();
2379            }
2380            mStackSupervisor.setFocusedStack(r);
2381            if (r != null) {
2382                mWindowManager.setFocusedApp(r.appToken, true);
2383            }
2384            applyUpdateLockStateLocked(r);
2385        }
2386    }
2387
2388    final void clearFocusedActivity(ActivityRecord r) {
2389        if (mFocusedActivity == r) {
2390            mFocusedActivity = null;
2391        }
2392    }
2393
2394    @Override
2395    public void setFocusedStack(int stackId) {
2396        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2397        synchronized (ActivityManagerService.this) {
2398            ActivityStack stack = mStackSupervisor.getStack(stackId);
2399            if (stack != null) {
2400                ActivityRecord r = stack.topRunningActivityLocked(null);
2401                if (r != null) {
2402                    setFocusedActivityLocked(r);
2403                }
2404            }
2405        }
2406    }
2407
2408    @Override
2409    public void notifyActivityDrawn(IBinder token) {
2410        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2411        synchronized (this) {
2412            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2413            if (r != null) {
2414                r.task.stack.notifyActivityDrawnLocked(r);
2415            }
2416        }
2417    }
2418
2419    final void applyUpdateLockStateLocked(ActivityRecord r) {
2420        // Modifications to the UpdateLock state are done on our handler, outside
2421        // the activity manager's locks.  The new state is determined based on the
2422        // state *now* of the relevant activity record.  The object is passed to
2423        // the handler solely for logging detail, not to be consulted/modified.
2424        final boolean nextState = r != null && r.immersive;
2425        mHandler.sendMessage(
2426                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2427    }
2428
2429    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2430        Message msg = Message.obtain();
2431        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2432        msg.obj = r.task.askedCompatMode ? null : r;
2433        mHandler.sendMessage(msg);
2434    }
2435
2436    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2437            String what, Object obj, ProcessRecord srcApp) {
2438        app.lastActivityTime = now;
2439
2440        if (app.activities.size() > 0) {
2441            // Don't want to touch dependent processes that are hosting activities.
2442            return index;
2443        }
2444
2445        int lrui = mLruProcesses.lastIndexOf(app);
2446        if (lrui < 0) {
2447            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2448                    + what + " " + obj + " from " + srcApp);
2449            return index;
2450        }
2451
2452        if (lrui >= index) {
2453            // Don't want to cause this to move dependent processes *back* in the
2454            // list as if they were less frequently used.
2455            return index;
2456        }
2457
2458        if (lrui >= mLruProcessActivityStart) {
2459            // Don't want to touch dependent processes that are hosting activities.
2460            return index;
2461        }
2462
2463        mLruProcesses.remove(lrui);
2464        if (index > 0) {
2465            index--;
2466        }
2467        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2468                + " in LRU list: " + app);
2469        mLruProcesses.add(index, app);
2470        return index;
2471    }
2472
2473    final void removeLruProcessLocked(ProcessRecord app) {
2474        int lrui = mLruProcesses.lastIndexOf(app);
2475        if (lrui >= 0) {
2476            if (lrui <= mLruProcessActivityStart) {
2477                mLruProcessActivityStart--;
2478            }
2479            if (lrui <= mLruProcessServiceStart) {
2480                mLruProcessServiceStart--;
2481            }
2482            mLruProcesses.remove(lrui);
2483        }
2484    }
2485
2486    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2487            ProcessRecord client) {
2488        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2489                || app.treatLikeActivity;
2490        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2491        if (!activityChange && hasActivity) {
2492            // The process has activities, so we are only allowing activity-based adjustments
2493            // to move it.  It should be kept in the front of the list with other
2494            // processes that have activities, and we don't want those to change their
2495            // order except due to activity operations.
2496            return;
2497        }
2498
2499        mLruSeq++;
2500        final long now = SystemClock.uptimeMillis();
2501        app.lastActivityTime = now;
2502
2503        // First a quick reject: if the app is already at the position we will
2504        // put it, then there is nothing to do.
2505        if (hasActivity) {
2506            final int N = mLruProcesses.size();
2507            if (N > 0 && mLruProcesses.get(N-1) == app) {
2508                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2509                return;
2510            }
2511        } else {
2512            if (mLruProcessServiceStart > 0
2513                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2514                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2515                return;
2516            }
2517        }
2518
2519        int lrui = mLruProcesses.lastIndexOf(app);
2520
2521        if (app.persistent && lrui >= 0) {
2522            // We don't care about the position of persistent processes, as long as
2523            // they are in the list.
2524            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2525            return;
2526        }
2527
2528        /* In progress: compute new position first, so we can avoid doing work
2529           if the process is not actually going to move.  Not yet working.
2530        int addIndex;
2531        int nextIndex;
2532        boolean inActivity = false, inService = false;
2533        if (hasActivity) {
2534            // Process has activities, put it at the very tipsy-top.
2535            addIndex = mLruProcesses.size();
2536            nextIndex = mLruProcessServiceStart;
2537            inActivity = true;
2538        } else if (hasService) {
2539            // Process has services, put it at the top of the service list.
2540            addIndex = mLruProcessActivityStart;
2541            nextIndex = mLruProcessServiceStart;
2542            inActivity = true;
2543            inService = true;
2544        } else  {
2545            // Process not otherwise of interest, it goes to the top of the non-service area.
2546            addIndex = mLruProcessServiceStart;
2547            if (client != null) {
2548                int clientIndex = mLruProcesses.lastIndexOf(client);
2549                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2550                        + app);
2551                if (clientIndex >= 0 && addIndex > clientIndex) {
2552                    addIndex = clientIndex;
2553                }
2554            }
2555            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2556        }
2557
2558        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2559                + mLruProcessActivityStart + "): " + app);
2560        */
2561
2562        if (lrui >= 0) {
2563            if (lrui < mLruProcessActivityStart) {
2564                mLruProcessActivityStart--;
2565            }
2566            if (lrui < mLruProcessServiceStart) {
2567                mLruProcessServiceStart--;
2568            }
2569            /*
2570            if (addIndex > lrui) {
2571                addIndex--;
2572            }
2573            if (nextIndex > lrui) {
2574                nextIndex--;
2575            }
2576            */
2577            mLruProcesses.remove(lrui);
2578        }
2579
2580        /*
2581        mLruProcesses.add(addIndex, app);
2582        if (inActivity) {
2583            mLruProcessActivityStart++;
2584        }
2585        if (inService) {
2586            mLruProcessActivityStart++;
2587        }
2588        */
2589
2590        int nextIndex;
2591        if (hasActivity) {
2592            final int N = mLruProcesses.size();
2593            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2594                // Process doesn't have activities, but has clients with
2595                // activities...  move it up, but one below the top (the top
2596                // should always have a real activity).
2597                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2598                mLruProcesses.add(N-1, app);
2599                // To keep it from spamming the LRU list (by making a bunch of clients),
2600                // we will push down any other entries owned by the app.
2601                final int uid = app.info.uid;
2602                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2603                    ProcessRecord subProc = mLruProcesses.get(i);
2604                    if (subProc.info.uid == uid) {
2605                        // We want to push this one down the list.  If the process after
2606                        // it is for the same uid, however, don't do so, because we don't
2607                        // want them internally to be re-ordered.
2608                        if (mLruProcesses.get(i-1).info.uid != uid) {
2609                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2610                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2611                            ProcessRecord tmp = mLruProcesses.get(i);
2612                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2613                            mLruProcesses.set(i-1, tmp);
2614                            i--;
2615                        }
2616                    } else {
2617                        // A gap, we can stop here.
2618                        break;
2619                    }
2620                }
2621            } else {
2622                // Process has activities, put it at the very tipsy-top.
2623                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2624                mLruProcesses.add(app);
2625            }
2626            nextIndex = mLruProcessServiceStart;
2627        } else if (hasService) {
2628            // Process has services, put it at the top of the service list.
2629            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2630            mLruProcesses.add(mLruProcessActivityStart, app);
2631            nextIndex = mLruProcessServiceStart;
2632            mLruProcessActivityStart++;
2633        } else  {
2634            // Process not otherwise of interest, it goes to the top of the non-service area.
2635            int index = mLruProcessServiceStart;
2636            if (client != null) {
2637                // If there is a client, don't allow the process to be moved up higher
2638                // in the list than that client.
2639                int clientIndex = mLruProcesses.lastIndexOf(client);
2640                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2641                        + " when updating " + app);
2642                if (clientIndex <= lrui) {
2643                    // Don't allow the client index restriction to push it down farther in the
2644                    // list than it already is.
2645                    clientIndex = lrui;
2646                }
2647                if (clientIndex >= 0 && index > clientIndex) {
2648                    index = clientIndex;
2649                }
2650            }
2651            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2652            mLruProcesses.add(index, app);
2653            nextIndex = index-1;
2654            mLruProcessActivityStart++;
2655            mLruProcessServiceStart++;
2656        }
2657
2658        // If the app is currently using a content provider or service,
2659        // bump those processes as well.
2660        for (int j=app.connections.size()-1; j>=0; j--) {
2661            ConnectionRecord cr = app.connections.valueAt(j);
2662            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2663                    && cr.binding.service.app != null
2664                    && cr.binding.service.app.lruSeq != mLruSeq
2665                    && !cr.binding.service.app.persistent) {
2666                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2667                        "service connection", cr, app);
2668            }
2669        }
2670        for (int j=app.conProviders.size()-1; j>=0; j--) {
2671            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2672            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2673                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2674                        "provider reference", cpr, app);
2675            }
2676        }
2677    }
2678
2679    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2680        if (uid == Process.SYSTEM_UID) {
2681            // The system gets to run in any process.  If there are multiple
2682            // processes with the same uid, just pick the first (this
2683            // should never happen).
2684            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2685            if (procs == null) return null;
2686            final int N = procs.size();
2687            for (int i = 0; i < N; i++) {
2688                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2689            }
2690        }
2691        ProcessRecord proc = mProcessNames.get(processName, uid);
2692        if (false && proc != null && !keepIfLarge
2693                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2694                && proc.lastCachedPss >= 4000) {
2695            // Turn this condition on to cause killing to happen regularly, for testing.
2696            if (proc.baseProcessTracker != null) {
2697                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2698            }
2699            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2700                    + "k from cached");
2701        } else if (proc != null && !keepIfLarge
2702                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2703                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2704            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2705            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2706                if (proc.baseProcessTracker != null) {
2707                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2708                }
2709                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2710                        + "k from cached");
2711            }
2712        }
2713        return proc;
2714    }
2715
2716    void ensurePackageDexOpt(String packageName) {
2717        IPackageManager pm = AppGlobals.getPackageManager();
2718        try {
2719            if (pm.performDexOpt(packageName)) {
2720                mDidDexOpt = true;
2721            }
2722        } catch (RemoteException e) {
2723        }
2724    }
2725
2726    boolean isNextTransitionForward() {
2727        int transit = mWindowManager.getPendingAppTransition();
2728        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2729                || transit == AppTransition.TRANSIT_TASK_OPEN
2730                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2731    }
2732
2733    final ProcessRecord startProcessLocked(String processName,
2734            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2735            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2736            boolean isolated, boolean keepIfLarge) {
2737        ProcessRecord app;
2738        if (!isolated) {
2739            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2740        } else {
2741            // If this is an isolated process, it can't re-use an existing process.
2742            app = null;
2743        }
2744        // We don't have to do anything more if:
2745        // (1) There is an existing application record; and
2746        // (2) The caller doesn't think it is dead, OR there is no thread
2747        //     object attached to it so we know it couldn't have crashed; and
2748        // (3) There is a pid assigned to it, so it is either starting or
2749        //     already running.
2750        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2751                + " app=" + app + " knownToBeDead=" + knownToBeDead
2752                + " thread=" + (app != null ? app.thread : null)
2753                + " pid=" + (app != null ? app.pid : -1));
2754        if (app != null && app.pid > 0) {
2755            if (!knownToBeDead || app.thread == null) {
2756                // We already have the app running, or are waiting for it to
2757                // come up (we have a pid but not yet its thread), so keep it.
2758                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2759                // If this is a new package in the process, add the package to the list
2760                app.addPackage(info.packageName, mProcessStats);
2761                return app;
2762            }
2763
2764            // An application record is attached to a previous process,
2765            // clean it up now.
2766            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2767            handleAppDiedLocked(app, true, true);
2768        }
2769
2770        String hostingNameStr = hostingName != null
2771                ? hostingName.flattenToShortString() : null;
2772
2773        if (!isolated) {
2774            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2775                // If we are in the background, then check to see if this process
2776                // is bad.  If so, we will just silently fail.
2777                if (mBadProcesses.get(info.processName, info.uid) != null) {
2778                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2779                            + "/" + info.processName);
2780                    return null;
2781                }
2782            } else {
2783                // When the user is explicitly starting a process, then clear its
2784                // crash count so that we won't make it bad until they see at
2785                // least one crash dialog again, and make the process good again
2786                // if it had been bad.
2787                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2788                        + "/" + info.processName);
2789                mProcessCrashTimes.remove(info.processName, info.uid);
2790                if (mBadProcesses.get(info.processName, info.uid) != null) {
2791                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2792                            UserHandle.getUserId(info.uid), info.uid,
2793                            info.processName);
2794                    mBadProcesses.remove(info.processName, info.uid);
2795                    if (app != null) {
2796                        app.bad = false;
2797                    }
2798                }
2799            }
2800        }
2801
2802        if (app == null) {
2803            app = newProcessRecordLocked(info, processName, isolated);
2804            if (app == null) {
2805                Slog.w(TAG, "Failed making new process record for "
2806                        + processName + "/" + info.uid + " isolated=" + isolated);
2807                return null;
2808            }
2809            mProcessNames.put(processName, app.uid, app);
2810            if (isolated) {
2811                mIsolatedProcesses.put(app.uid, app);
2812            }
2813        } else {
2814            // If this is a new package in the process, add the package to the list
2815            app.addPackage(info.packageName, mProcessStats);
2816        }
2817
2818        // If the system is not ready yet, then hold off on starting this
2819        // process until it is.
2820        if (!mProcessesReady
2821                && !isAllowedWhileBooting(info)
2822                && !allowWhileBooting) {
2823            if (!mProcessesOnHold.contains(app)) {
2824                mProcessesOnHold.add(app);
2825            }
2826            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2827            return app;
2828        }
2829
2830        startProcessLocked(app, hostingType, hostingNameStr);
2831        return (app.pid != 0) ? app : null;
2832    }
2833
2834    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2835        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2836    }
2837
2838    private final void startProcessLocked(ProcessRecord app,
2839            String hostingType, String hostingNameStr) {
2840        if (app.pid > 0 && app.pid != MY_PID) {
2841            synchronized (mPidsSelfLocked) {
2842                mPidsSelfLocked.remove(app.pid);
2843                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2844            }
2845            app.setPid(0);
2846        }
2847
2848        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2849                "startProcessLocked removing on hold: " + app);
2850        mProcessesOnHold.remove(app);
2851
2852        updateCpuStats();
2853
2854        try {
2855            int uid = app.uid;
2856
2857            int[] gids = null;
2858            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2859            if (!app.isolated) {
2860                int[] permGids = null;
2861                try {
2862                    final PackageManager pm = mContext.getPackageManager();
2863                    permGids = pm.getPackageGids(app.info.packageName);
2864
2865                    if (Environment.isExternalStorageEmulated()) {
2866                        if (pm.checkPermission(
2867                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2868                                app.info.packageName) == PERMISSION_GRANTED) {
2869                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2870                        } else {
2871                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2872                        }
2873                    }
2874                } catch (PackageManager.NameNotFoundException e) {
2875                    Slog.w(TAG, "Unable to retrieve gids", e);
2876                }
2877
2878                /*
2879                 * Add shared application GID so applications can share some
2880                 * resources like shared libraries
2881                 */
2882                if (permGids == null) {
2883                    gids = new int[1];
2884                } else {
2885                    gids = new int[permGids.length + 1];
2886                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2887                }
2888                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2889            }
2890            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2891                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2892                        && mTopComponent != null
2893                        && app.processName.equals(mTopComponent.getPackageName())) {
2894                    uid = 0;
2895                }
2896                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2897                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2898                    uid = 0;
2899                }
2900            }
2901            int debugFlags = 0;
2902            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2903                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2904                // Also turn on CheckJNI for debuggable apps. It's quite
2905                // awkward to turn on otherwise.
2906                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2907            }
2908            // Run the app in safe mode if its manifest requests so or the
2909            // system is booted in safe mode.
2910            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2911                mSafeMode == true) {
2912                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2913            }
2914            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2915                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2916            }
2917            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2918                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2919            }
2920            if ("1".equals(SystemProperties.get("debug.assert"))) {
2921                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2922            }
2923
2924            String requiredAbi = app.info.cpuAbi;
2925            if (requiredAbi == null) {
2926                requiredAbi = Build.SUPPORTED_ABIS[0];
2927            }
2928
2929            // Start the process.  It will either succeed and return a result containing
2930            // the PID of the new process, or else throw a RuntimeException.
2931            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2932                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2933                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2934
2935            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2936            synchronized (bs) {
2937                if (bs.isOnBattery()) {
2938                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2939                }
2940            }
2941
2942            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2943                    UserHandle.getUserId(uid), startResult.pid, uid,
2944                    app.processName, hostingType,
2945                    hostingNameStr != null ? hostingNameStr : "");
2946
2947            if (app.persistent) {
2948                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2949            }
2950
2951            StringBuilder buf = mStringBuilder;
2952            buf.setLength(0);
2953            buf.append("Start proc ");
2954            buf.append(app.processName);
2955            buf.append(" for ");
2956            buf.append(hostingType);
2957            if (hostingNameStr != null) {
2958                buf.append(" ");
2959                buf.append(hostingNameStr);
2960            }
2961            buf.append(": pid=");
2962            buf.append(startResult.pid);
2963            buf.append(" uid=");
2964            buf.append(uid);
2965            buf.append(" gids={");
2966            if (gids != null) {
2967                for (int gi=0; gi<gids.length; gi++) {
2968                    if (gi != 0) buf.append(", ");
2969                    buf.append(gids[gi]);
2970
2971                }
2972            }
2973            buf.append("}");
2974            Slog.i(TAG, buf.toString());
2975            app.setPid(startResult.pid);
2976            app.usingWrapper = startResult.usingWrapper;
2977            app.removed = false;
2978            synchronized (mPidsSelfLocked) {
2979                this.mPidsSelfLocked.put(startResult.pid, app);
2980                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2981                msg.obj = app;
2982                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2983                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2984            }
2985            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2986                    app.processName, app.info.uid);
2987            if (app.isolated) {
2988                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2989            }
2990        } catch (RuntimeException e) {
2991            // XXX do better error recovery.
2992            app.setPid(0);
2993            Slog.e(TAG, "Failure starting process " + app.processName, e);
2994        }
2995    }
2996
2997    void updateUsageStats(ActivityRecord component, boolean resumed) {
2998        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2999        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3000        if (resumed) {
3001            mUsageStatsService.noteResumeComponent(component.realActivity);
3002            synchronized (stats) {
3003                stats.noteActivityResumedLocked(component.app.uid);
3004            }
3005        } else {
3006            mUsageStatsService.notePauseComponent(component.realActivity);
3007            synchronized (stats) {
3008                stats.noteActivityPausedLocked(component.app.uid);
3009            }
3010        }
3011    }
3012
3013    Intent getHomeIntent() {
3014        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3015        intent.setComponent(mTopComponent);
3016        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3017            intent.addCategory(Intent.CATEGORY_HOME);
3018        }
3019        return intent;
3020    }
3021
3022    boolean startHomeActivityLocked(int userId) {
3023        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3024                && mTopAction == null) {
3025            // We are running in factory test mode, but unable to find
3026            // the factory test app, so just sit around displaying the
3027            // error message and don't try to start anything.
3028            return false;
3029        }
3030        Intent intent = getHomeIntent();
3031        ActivityInfo aInfo =
3032            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3033        if (aInfo != null) {
3034            intent.setComponent(new ComponentName(
3035                    aInfo.applicationInfo.packageName, aInfo.name));
3036            // Don't do this if the home app is currently being
3037            // instrumented.
3038            aInfo = new ActivityInfo(aInfo);
3039            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3040            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3041                    aInfo.applicationInfo.uid, true);
3042            if (app == null || app.instrumentationClass == null) {
3043                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3044                mStackSupervisor.startHomeActivity(intent, aInfo);
3045            }
3046        }
3047
3048        return true;
3049    }
3050
3051    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3052        ActivityInfo ai = null;
3053        ComponentName comp = intent.getComponent();
3054        try {
3055            if (comp != null) {
3056                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3057            } else {
3058                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3059                        intent,
3060                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3061                            flags, userId);
3062
3063                if (info != null) {
3064                    ai = info.activityInfo;
3065                }
3066            }
3067        } catch (RemoteException e) {
3068            // ignore
3069        }
3070
3071        return ai;
3072    }
3073
3074    /**
3075     * Starts the "new version setup screen" if appropriate.
3076     */
3077    void startSetupActivityLocked() {
3078        // Only do this once per boot.
3079        if (mCheckedForSetup) {
3080            return;
3081        }
3082
3083        // We will show this screen if the current one is a different
3084        // version than the last one shown, and we are not running in
3085        // low-level factory test mode.
3086        final ContentResolver resolver = mContext.getContentResolver();
3087        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3088                Settings.Global.getInt(resolver,
3089                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3090            mCheckedForSetup = true;
3091
3092            // See if we should be showing the platform update setup UI.
3093            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3094            List<ResolveInfo> ris = mContext.getPackageManager()
3095                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3096
3097            // We don't allow third party apps to replace this.
3098            ResolveInfo ri = null;
3099            for (int i=0; ris != null && i<ris.size(); i++) {
3100                if ((ris.get(i).activityInfo.applicationInfo.flags
3101                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3102                    ri = ris.get(i);
3103                    break;
3104                }
3105            }
3106
3107            if (ri != null) {
3108                String vers = ri.activityInfo.metaData != null
3109                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3110                        : null;
3111                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3112                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3113                            Intent.METADATA_SETUP_VERSION);
3114                }
3115                String lastVers = Settings.Secure.getString(
3116                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3117                if (vers != null && !vers.equals(lastVers)) {
3118                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3119                    intent.setComponent(new ComponentName(
3120                            ri.activityInfo.packageName, ri.activityInfo.name));
3121                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3122                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3123                }
3124            }
3125        }
3126    }
3127
3128    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3129        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3130    }
3131
3132    void enforceNotIsolatedCaller(String caller) {
3133        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3134            throw new SecurityException("Isolated process not allowed to call " + caller);
3135        }
3136    }
3137
3138    @Override
3139    public int getFrontActivityScreenCompatMode() {
3140        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3141        synchronized (this) {
3142            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3143        }
3144    }
3145
3146    @Override
3147    public void setFrontActivityScreenCompatMode(int mode) {
3148        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3149                "setFrontActivityScreenCompatMode");
3150        synchronized (this) {
3151            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3152        }
3153    }
3154
3155    @Override
3156    public int getPackageScreenCompatMode(String packageName) {
3157        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3158        synchronized (this) {
3159            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3160        }
3161    }
3162
3163    @Override
3164    public void setPackageScreenCompatMode(String packageName, int mode) {
3165        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3166                "setPackageScreenCompatMode");
3167        synchronized (this) {
3168            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3169        }
3170    }
3171
3172    @Override
3173    public boolean getPackageAskScreenCompat(String packageName) {
3174        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3175        synchronized (this) {
3176            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3177        }
3178    }
3179
3180    @Override
3181    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3182        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3183                "setPackageAskScreenCompat");
3184        synchronized (this) {
3185            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3186        }
3187    }
3188
3189    private void dispatchProcessesChanged() {
3190        int N;
3191        synchronized (this) {
3192            N = mPendingProcessChanges.size();
3193            if (mActiveProcessChanges.length < N) {
3194                mActiveProcessChanges = new ProcessChangeItem[N];
3195            }
3196            mPendingProcessChanges.toArray(mActiveProcessChanges);
3197            mAvailProcessChanges.addAll(mPendingProcessChanges);
3198            mPendingProcessChanges.clear();
3199            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3200        }
3201
3202        int i = mProcessObservers.beginBroadcast();
3203        while (i > 0) {
3204            i--;
3205            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3206            if (observer != null) {
3207                try {
3208                    for (int j=0; j<N; j++) {
3209                        ProcessChangeItem item = mActiveProcessChanges[j];
3210                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3211                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3212                                    + item.pid + " uid=" + item.uid + ": "
3213                                    + item.foregroundActivities);
3214                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3215                                    item.foregroundActivities);
3216                        }
3217                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3218                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3219                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3220                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3221                        }
3222                    }
3223                } catch (RemoteException e) {
3224                }
3225            }
3226        }
3227        mProcessObservers.finishBroadcast();
3228    }
3229
3230    private void dispatchProcessDied(int pid, int uid) {
3231        int i = mProcessObservers.beginBroadcast();
3232        while (i > 0) {
3233            i--;
3234            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3235            if (observer != null) {
3236                try {
3237                    observer.onProcessDied(pid, uid);
3238                } catch (RemoteException e) {
3239                }
3240            }
3241        }
3242        mProcessObservers.finishBroadcast();
3243    }
3244
3245    final void doPendingActivityLaunchesLocked(boolean doResume) {
3246        final int N = mPendingActivityLaunches.size();
3247        if (N <= 0) {
3248            return;
3249        }
3250        for (int i=0; i<N; i++) {
3251            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3252            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3253                    doResume && i == (N-1), null);
3254        }
3255        mPendingActivityLaunches.clear();
3256    }
3257
3258    @Override
3259    public final int startActivity(IApplicationThread caller, String callingPackage,
3260            Intent intent, String resolvedType, IBinder resultTo,
3261            String resultWho, int requestCode, int startFlags,
3262            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3263        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3264                resultWho, requestCode,
3265                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3266    }
3267
3268    @Override
3269    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3270            Intent intent, String resolvedType, IBinder resultTo,
3271            String resultWho, int requestCode, int startFlags,
3272            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3273        enforceNotIsolatedCaller("startActivity");
3274        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3275                false, true, "startActivity", null);
3276        // TODO: Switch to user app stacks here.
3277        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3278                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3279                null, null, options, userId, null);
3280    }
3281
3282    @Override
3283    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3284            Intent intent, String resolvedType, IBinder resultTo,
3285            String resultWho, int requestCode, int startFlags, String profileFile,
3286            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3287        enforceNotIsolatedCaller("startActivityAndWait");
3288        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3289                false, true, "startActivityAndWait", null);
3290        WaitResult res = new WaitResult();
3291        // TODO: Switch to user app stacks here.
3292        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3293                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3294                res, null, options, UserHandle.getCallingUserId(), null);
3295        return res;
3296    }
3297
3298    @Override
3299    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3300            Intent intent, String resolvedType, IBinder resultTo,
3301            String resultWho, int requestCode, int startFlags, Configuration config,
3302            Bundle options, int userId) {
3303        enforceNotIsolatedCaller("startActivityWithConfig");
3304        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3305                false, true, "startActivityWithConfig", null);
3306        // TODO: Switch to user app stacks here.
3307        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3308                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3309                null, null, null, config, options, userId, null);
3310        return ret;
3311    }
3312
3313    @Override
3314    public int startActivityIntentSender(IApplicationThread caller,
3315            IntentSender intent, Intent fillInIntent, String resolvedType,
3316            IBinder resultTo, String resultWho, int requestCode,
3317            int flagsMask, int flagsValues, Bundle options) {
3318        enforceNotIsolatedCaller("startActivityIntentSender");
3319        // Refuse possible leaked file descriptors
3320        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3321            throw new IllegalArgumentException("File descriptors passed in Intent");
3322        }
3323
3324        IIntentSender sender = intent.getTarget();
3325        if (!(sender instanceof PendingIntentRecord)) {
3326            throw new IllegalArgumentException("Bad PendingIntent object");
3327        }
3328
3329        PendingIntentRecord pir = (PendingIntentRecord)sender;
3330
3331        synchronized (this) {
3332            // If this is coming from the currently resumed activity, it is
3333            // effectively saying that app switches are allowed at this point.
3334            final ActivityStack stack = getFocusedStack();
3335            if (stack.mResumedActivity != null &&
3336                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3337                mAppSwitchesAllowedTime = 0;
3338            }
3339        }
3340        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3341                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3342        return ret;
3343    }
3344
3345    @Override
3346    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3347            Intent intent, String resolvedType, IVoiceInteractionSession session,
3348            IVoiceInteractor interactor, int startFlags, String profileFile,
3349            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3350        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3351                != PackageManager.PERMISSION_GRANTED) {
3352            String msg = "Permission Denial: startVoiceActivity() from pid="
3353                    + Binder.getCallingPid()
3354                    + ", uid=" + Binder.getCallingUid()
3355                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3356            Slog.w(TAG, msg);
3357            throw new SecurityException(msg);
3358        }
3359        if (session == null || interactor == null) {
3360            throw new NullPointerException("null session or interactor");
3361        }
3362        userId = handleIncomingUser(callingPid, callingUid, userId,
3363                false, true, "startVoiceActivity", null);
3364        // TODO: Switch to user app stacks here.
3365        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3366                resolvedType, session, interactor, null, null, 0, startFlags,
3367                profileFile, profileFd, null, null, options, userId, null);
3368    }
3369
3370    @Override
3371    public boolean startNextMatchingActivity(IBinder callingActivity,
3372            Intent intent, Bundle options) {
3373        // Refuse possible leaked file descriptors
3374        if (intent != null && intent.hasFileDescriptors() == true) {
3375            throw new IllegalArgumentException("File descriptors passed in Intent");
3376        }
3377
3378        synchronized (this) {
3379            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3380            if (r == null) {
3381                ActivityOptions.abort(options);
3382                return false;
3383            }
3384            if (r.app == null || r.app.thread == null) {
3385                // The caller is not running...  d'oh!
3386                ActivityOptions.abort(options);
3387                return false;
3388            }
3389            intent = new Intent(intent);
3390            // The caller is not allowed to change the data.
3391            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3392            // And we are resetting to find the next component...
3393            intent.setComponent(null);
3394
3395            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3396
3397            ActivityInfo aInfo = null;
3398            try {
3399                List<ResolveInfo> resolves =
3400                    AppGlobals.getPackageManager().queryIntentActivities(
3401                            intent, r.resolvedType,
3402                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3403                            UserHandle.getCallingUserId());
3404
3405                // Look for the original activity in the list...
3406                final int N = resolves != null ? resolves.size() : 0;
3407                for (int i=0; i<N; i++) {
3408                    ResolveInfo rInfo = resolves.get(i);
3409                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3410                            && rInfo.activityInfo.name.equals(r.info.name)) {
3411                        // We found the current one...  the next matching is
3412                        // after it.
3413                        i++;
3414                        if (i<N) {
3415                            aInfo = resolves.get(i).activityInfo;
3416                        }
3417                        if (debug) {
3418                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3419                                    + "/" + r.info.name);
3420                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3421                                    + "/" + aInfo.name);
3422                        }
3423                        break;
3424                    }
3425                }
3426            } catch (RemoteException e) {
3427            }
3428
3429            if (aInfo == null) {
3430                // Nobody who is next!
3431                ActivityOptions.abort(options);
3432                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3433                return false;
3434            }
3435
3436            intent.setComponent(new ComponentName(
3437                    aInfo.applicationInfo.packageName, aInfo.name));
3438            intent.setFlags(intent.getFlags()&~(
3439                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3440                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3441                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3442                    Intent.FLAG_ACTIVITY_NEW_TASK));
3443
3444            // Okay now we need to start the new activity, replacing the
3445            // currently running activity.  This is a little tricky because
3446            // we want to start the new one as if the current one is finished,
3447            // but not finish the current one first so that there is no flicker.
3448            // And thus...
3449            final boolean wasFinishing = r.finishing;
3450            r.finishing = true;
3451
3452            // Propagate reply information over to the new activity.
3453            final ActivityRecord resultTo = r.resultTo;
3454            final String resultWho = r.resultWho;
3455            final int requestCode = r.requestCode;
3456            r.resultTo = null;
3457            if (resultTo != null) {
3458                resultTo.removeResultsLocked(r, resultWho, requestCode);
3459            }
3460
3461            final long origId = Binder.clearCallingIdentity();
3462            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3463                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3464                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3465                    options, false, null, null);
3466            Binder.restoreCallingIdentity(origId);
3467
3468            r.finishing = wasFinishing;
3469            if (res != ActivityManager.START_SUCCESS) {
3470                return false;
3471            }
3472            return true;
3473        }
3474    }
3475
3476    final int startActivityInPackage(int uid, String callingPackage,
3477            Intent intent, String resolvedType, IBinder resultTo,
3478            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3479                    IActivityContainer container) {
3480
3481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3482                false, true, "startActivityInPackage", null);
3483
3484        // TODO: Switch to user app stacks here.
3485        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3486                null, null, resultTo, resultWho, requestCode, startFlags,
3487                null, null, null, null, options, userId, container);
3488        return ret;
3489    }
3490
3491    @Override
3492    public final int startActivities(IApplicationThread caller, String callingPackage,
3493            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3494            int userId) {
3495        enforceNotIsolatedCaller("startActivities");
3496        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3497                false, true, "startActivity", null);
3498        // TODO: Switch to user app stacks here.
3499        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3500                resolvedTypes, resultTo, options, userId);
3501        return ret;
3502    }
3503
3504    final int startActivitiesInPackage(int uid, String callingPackage,
3505            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3506            Bundle options, int userId) {
3507
3508        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3509                false, true, "startActivityInPackage", null);
3510        // TODO: Switch to user app stacks here.
3511        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3512                resultTo, options, userId);
3513        return ret;
3514    }
3515
3516    final void addRecentTaskLocked(TaskRecord task) {
3517        int N = mRecentTasks.size();
3518        // Quick case: check if the top-most recent task is the same.
3519        if (N > 0 && mRecentTasks.get(0) == task) {
3520            return;
3521        }
3522        // Another quick case: never add voice sessions.
3523        if (task.voiceSession != null) {
3524            return;
3525        }
3526        // Remove any existing entries that are the same kind of task.
3527        final Intent intent = task.intent;
3528        final boolean document = intent != null && intent.isDocument();
3529        for (int i=0; i<N; i++) {
3530            TaskRecord tr = mRecentTasks.get(i);
3531            if (task != tr) {
3532                if (task.userId != tr.userId) {
3533                    continue;
3534                }
3535                final Intent trIntent = tr.intent;
3536                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3537                    (intent == null || !intent.filterEquals(trIntent))) {
3538                    continue;
3539                }
3540                if (document || trIntent != null && trIntent.isDocument()) {
3541                    // Document tasks do not match other tasks.
3542                    continue;
3543                }
3544            }
3545
3546            // Either task and tr are the same or, their affinities match or their intents match
3547            // and neither of them is a document.
3548            tr.disposeThumbnail();
3549            mRecentTasks.remove(i);
3550            i--;
3551            N--;
3552            if (task.intent == null) {
3553                // If the new recent task we are adding is not fully
3554                // specified, then replace it with the existing recent task.
3555                task = tr;
3556            }
3557        }
3558        if (N >= MAX_RECENT_TASKS) {
3559            mRecentTasks.remove(N-1).disposeThumbnail();
3560        }
3561        mRecentTasks.add(0, task);
3562    }
3563
3564    @Override
3565    public void reportActivityFullyDrawn(IBinder token) {
3566        synchronized (this) {
3567            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3568            if (r == null) {
3569                return;
3570            }
3571            r.reportFullyDrawnLocked();
3572        }
3573    }
3574
3575    @Override
3576    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3577        synchronized (this) {
3578            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3579            if (r == null) {
3580                return;
3581            }
3582            final long origId = Binder.clearCallingIdentity();
3583            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3584            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3585                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3586            if (config != null) {
3587                r.frozenBeforeDestroy = true;
3588                if (!updateConfigurationLocked(config, r, false, false)) {
3589                    mStackSupervisor.resumeTopActivitiesLocked();
3590                }
3591            }
3592            Binder.restoreCallingIdentity(origId);
3593        }
3594    }
3595
3596    @Override
3597    public int getRequestedOrientation(IBinder token) {
3598        synchronized (this) {
3599            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3600            if (r == null) {
3601                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3602            }
3603            return mWindowManager.getAppOrientation(r.appToken);
3604        }
3605    }
3606
3607    /**
3608     * This is the internal entry point for handling Activity.finish().
3609     *
3610     * @param token The Binder token referencing the Activity we want to finish.
3611     * @param resultCode Result code, if any, from this Activity.
3612     * @param resultData Result data (Intent), if any, from this Activity.
3613     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3614     *            the root Activity in the task.
3615     *
3616     * @return Returns true if the activity successfully finished, or false if it is still running.
3617     */
3618    @Override
3619    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3620            boolean finishTask) {
3621        // Refuse possible leaked file descriptors
3622        if (resultData != null && resultData.hasFileDescriptors() == true) {
3623            throw new IllegalArgumentException("File descriptors passed in Intent");
3624        }
3625
3626        synchronized(this) {
3627            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3628            if (r == null) {
3629                return true;
3630            }
3631            // Keep track of the root activity of the task before we finish it
3632            TaskRecord tr = r.task;
3633            ActivityRecord rootR = tr.getRootActivity();
3634            if (mController != null) {
3635                // Find the first activity that is not finishing.
3636                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3637                if (next != null) {
3638                    // ask watcher if this is allowed
3639                    boolean resumeOK = true;
3640                    try {
3641                        resumeOK = mController.activityResuming(next.packageName);
3642                    } catch (RemoteException e) {
3643                        mController = null;
3644                        Watchdog.getInstance().setActivityController(null);
3645                    }
3646
3647                    if (!resumeOK) {
3648                        return false;
3649                    }
3650                }
3651            }
3652            final long origId = Binder.clearCallingIdentity();
3653            try {
3654                boolean res;
3655                if (finishTask && r == rootR) {
3656                    // If requested, remove the task that is associated to this activity only if it
3657                    // was the root activity in the task.  The result code and data is ignored because
3658                    // we don't support returning them across task boundaries.
3659                    res = removeTaskByIdLocked(tr.taskId, 0);
3660                } else {
3661                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3662                            resultData, "app-request", true);
3663                }
3664                return res;
3665            } finally {
3666                Binder.restoreCallingIdentity(origId);
3667            }
3668        }
3669    }
3670
3671    @Override
3672    public final void finishHeavyWeightApp() {
3673        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3674                != PackageManager.PERMISSION_GRANTED) {
3675            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3676                    + Binder.getCallingPid()
3677                    + ", uid=" + Binder.getCallingUid()
3678                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3679            Slog.w(TAG, msg);
3680            throw new SecurityException(msg);
3681        }
3682
3683        synchronized(this) {
3684            if (mHeavyWeightProcess == null) {
3685                return;
3686            }
3687
3688            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3689                    mHeavyWeightProcess.activities);
3690            for (int i=0; i<activities.size(); i++) {
3691                ActivityRecord r = activities.get(i);
3692                if (!r.finishing) {
3693                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3694                            null, "finish-heavy", true);
3695                }
3696            }
3697
3698            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3699                    mHeavyWeightProcess.userId, 0));
3700            mHeavyWeightProcess = null;
3701        }
3702    }
3703
3704    @Override
3705    public void crashApplication(int uid, int initialPid, String packageName,
3706            String message) {
3707        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3708                != PackageManager.PERMISSION_GRANTED) {
3709            String msg = "Permission Denial: crashApplication() from pid="
3710                    + Binder.getCallingPid()
3711                    + ", uid=" + Binder.getCallingUid()
3712                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3713            Slog.w(TAG, msg);
3714            throw new SecurityException(msg);
3715        }
3716
3717        synchronized(this) {
3718            ProcessRecord proc = null;
3719
3720            // Figure out which process to kill.  We don't trust that initialPid
3721            // still has any relation to current pids, so must scan through the
3722            // list.
3723            synchronized (mPidsSelfLocked) {
3724                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3725                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3726                    if (p.uid != uid) {
3727                        continue;
3728                    }
3729                    if (p.pid == initialPid) {
3730                        proc = p;
3731                        break;
3732                    }
3733                    if (p.pkgList.containsKey(packageName)) {
3734                        proc = p;
3735                    }
3736                }
3737            }
3738
3739            if (proc == null) {
3740                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3741                        + " initialPid=" + initialPid
3742                        + " packageName=" + packageName);
3743                return;
3744            }
3745
3746            if (proc.thread != null) {
3747                if (proc.pid == Process.myPid()) {
3748                    Log.w(TAG, "crashApplication: trying to crash self!");
3749                    return;
3750                }
3751                long ident = Binder.clearCallingIdentity();
3752                try {
3753                    proc.thread.scheduleCrash(message);
3754                } catch (RemoteException e) {
3755                }
3756                Binder.restoreCallingIdentity(ident);
3757            }
3758        }
3759    }
3760
3761    @Override
3762    public final void finishSubActivity(IBinder token, String resultWho,
3763            int requestCode) {
3764        synchronized(this) {
3765            final long origId = Binder.clearCallingIdentity();
3766            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3767            if (r != null) {
3768                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3769            }
3770            Binder.restoreCallingIdentity(origId);
3771        }
3772    }
3773
3774    @Override
3775    public boolean finishActivityAffinity(IBinder token) {
3776        synchronized(this) {
3777            final long origId = Binder.clearCallingIdentity();
3778            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3779            boolean res = false;
3780            if (r != null) {
3781                res = r.task.stack.finishActivityAffinityLocked(r);
3782            }
3783            Binder.restoreCallingIdentity(origId);
3784            return res;
3785        }
3786    }
3787
3788    @Override
3789    public boolean willActivityBeVisible(IBinder token) {
3790        synchronized(this) {
3791            ActivityStack stack = ActivityRecord.getStackLocked(token);
3792            if (stack != null) {
3793                return stack.willActivityBeVisibleLocked(token);
3794            }
3795            return false;
3796        }
3797    }
3798
3799    @Override
3800    public void overridePendingTransition(IBinder token, String packageName,
3801            int enterAnim, int exitAnim) {
3802        synchronized(this) {
3803            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3804            if (self == null) {
3805                return;
3806            }
3807
3808            final long origId = Binder.clearCallingIdentity();
3809
3810            if (self.state == ActivityState.RESUMED
3811                    || self.state == ActivityState.PAUSING) {
3812                mWindowManager.overridePendingAppTransition(packageName,
3813                        enterAnim, exitAnim, null);
3814            }
3815
3816            Binder.restoreCallingIdentity(origId);
3817        }
3818    }
3819
3820    /**
3821     * Main function for removing an existing process from the activity manager
3822     * as a result of that process going away.  Clears out all connections
3823     * to the process.
3824     */
3825    private final void handleAppDiedLocked(ProcessRecord app,
3826            boolean restarting, boolean allowRestart) {
3827        int pid = app.pid;
3828        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3829        if (!restarting) {
3830            removeLruProcessLocked(app);
3831            if (pid > 0) {
3832                ProcessList.remove(pid);
3833            }
3834        }
3835
3836        if (mProfileProc == app) {
3837            clearProfilerLocked();
3838        }
3839
3840        // Remove this application's activities from active lists.
3841        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3842
3843        app.activities.clear();
3844
3845        if (app.instrumentationClass != null) {
3846            Slog.w(TAG, "Crash of app " + app.processName
3847                  + " running instrumentation " + app.instrumentationClass);
3848            Bundle info = new Bundle();
3849            info.putString("shortMsg", "Process crashed.");
3850            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3851        }
3852
3853        if (!restarting) {
3854            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3855                // If there was nothing to resume, and we are not already
3856                // restarting this process, but there is a visible activity that
3857                // is hosted by the process...  then make sure all visible
3858                // activities are running, taking care of restarting this
3859                // process.
3860                if (hasVisibleActivities) {
3861                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3862                }
3863            }
3864        }
3865    }
3866
3867    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3868        IBinder threadBinder = thread.asBinder();
3869        // Find the application record.
3870        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3871            ProcessRecord rec = mLruProcesses.get(i);
3872            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3873                return i;
3874            }
3875        }
3876        return -1;
3877    }
3878
3879    final ProcessRecord getRecordForAppLocked(
3880            IApplicationThread thread) {
3881        if (thread == null) {
3882            return null;
3883        }
3884
3885        int appIndex = getLRURecordIndexForAppLocked(thread);
3886        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3887    }
3888
3889    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3890        // If there are no longer any background processes running,
3891        // and the app that died was not running instrumentation,
3892        // then tell everyone we are now low on memory.
3893        boolean haveBg = false;
3894        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3895            ProcessRecord rec = mLruProcesses.get(i);
3896            if (rec.thread != null
3897                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3898                haveBg = true;
3899                break;
3900            }
3901        }
3902
3903        if (!haveBg) {
3904            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3905            if (doReport) {
3906                long now = SystemClock.uptimeMillis();
3907                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3908                    doReport = false;
3909                } else {
3910                    mLastMemUsageReportTime = now;
3911                }
3912            }
3913            final ArrayList<ProcessMemInfo> memInfos
3914                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3915            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3916            long now = SystemClock.uptimeMillis();
3917            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3918                ProcessRecord rec = mLruProcesses.get(i);
3919                if (rec == dyingProc || rec.thread == null) {
3920                    continue;
3921                }
3922                if (doReport) {
3923                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3924                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3925                }
3926                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3927                    // The low memory report is overriding any current
3928                    // state for a GC request.  Make sure to do
3929                    // heavy/important/visible/foreground processes first.
3930                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3931                        rec.lastRequestedGc = 0;
3932                    } else {
3933                        rec.lastRequestedGc = rec.lastLowMemory;
3934                    }
3935                    rec.reportLowMemory = true;
3936                    rec.lastLowMemory = now;
3937                    mProcessesToGc.remove(rec);
3938                    addProcessToGcListLocked(rec);
3939                }
3940            }
3941            if (doReport) {
3942                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3943                mHandler.sendMessage(msg);
3944            }
3945            scheduleAppGcsLocked();
3946        }
3947    }
3948
3949    final void appDiedLocked(ProcessRecord app, int pid,
3950            IApplicationThread thread) {
3951
3952        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3953        synchronized (stats) {
3954            stats.noteProcessDiedLocked(app.info.uid, pid);
3955        }
3956
3957        // Clean up already done if the process has been re-started.
3958        if (app.pid == pid && app.thread != null &&
3959                app.thread.asBinder() == thread.asBinder()) {
3960            boolean doLowMem = app.instrumentationClass == null;
3961            boolean doOomAdj = doLowMem;
3962            if (!app.killedByAm) {
3963                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3964                        + ") has died.");
3965                mAllowLowerMemLevel = true;
3966            } else {
3967                // Note that we always want to do oom adj to update our state with the
3968                // new number of procs.
3969                mAllowLowerMemLevel = false;
3970                doLowMem = false;
3971            }
3972            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3973            if (DEBUG_CLEANUP) Slog.v(
3974                TAG, "Dying app: " + app + ", pid: " + pid
3975                + ", thread: " + thread.asBinder());
3976            handleAppDiedLocked(app, false, true);
3977
3978            if (doOomAdj) {
3979                updateOomAdjLocked();
3980            }
3981            if (doLowMem) {
3982                doLowMemReportIfNeededLocked(app);
3983            }
3984        } else if (app.pid != pid) {
3985            // A new process has already been started.
3986            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3987                    + ") has died and restarted (pid " + app.pid + ").");
3988            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3989        } else if (DEBUG_PROCESSES) {
3990            Slog.d(TAG, "Received spurious death notification for thread "
3991                    + thread.asBinder());
3992        }
3993    }
3994
3995    /**
3996     * If a stack trace dump file is configured, dump process stack traces.
3997     * @param clearTraces causes the dump file to be erased prior to the new
3998     *    traces being written, if true; when false, the new traces will be
3999     *    appended to any existing file content.
4000     * @param firstPids of dalvik VM processes to dump stack traces for first
4001     * @param lastPids of dalvik VM processes to dump stack traces for last
4002     * @param nativeProcs optional list of native process names to dump stack crawls
4003     * @return file containing stack traces, or null if no dump file is configured
4004     */
4005    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4006            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4007        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4008        if (tracesPath == null || tracesPath.length() == 0) {
4009            return null;
4010        }
4011
4012        File tracesFile = new File(tracesPath);
4013        try {
4014            File tracesDir = tracesFile.getParentFile();
4015            if (!tracesDir.exists()) {
4016                tracesFile.mkdirs();
4017                if (!SELinux.restorecon(tracesDir)) {
4018                    return null;
4019                }
4020            }
4021            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4022
4023            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4024            tracesFile.createNewFile();
4025            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4026        } catch (IOException e) {
4027            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4028            return null;
4029        }
4030
4031        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4032        return tracesFile;
4033    }
4034
4035    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4036            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4037        // Use a FileObserver to detect when traces finish writing.
4038        // The order of traces is considered important to maintain for legibility.
4039        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4040            @Override
4041            public synchronized void onEvent(int event, String path) { notify(); }
4042        };
4043
4044        try {
4045            observer.startWatching();
4046
4047            // First collect all of the stacks of the most important pids.
4048            if (firstPids != null) {
4049                try {
4050                    int num = firstPids.size();
4051                    for (int i = 0; i < num; i++) {
4052                        synchronized (observer) {
4053                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4054                            observer.wait(200);  // Wait for write-close, give up after 200msec
4055                        }
4056                    }
4057                } catch (InterruptedException e) {
4058                    Log.wtf(TAG, e);
4059                }
4060            }
4061
4062            // Next collect the stacks of the native pids
4063            if (nativeProcs != null) {
4064                int[] pids = Process.getPidsForCommands(nativeProcs);
4065                if (pids != null) {
4066                    for (int pid : pids) {
4067                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4068                    }
4069                }
4070            }
4071
4072            // Lastly, measure CPU usage.
4073            if (processCpuTracker != null) {
4074                processCpuTracker.init();
4075                System.gc();
4076                processCpuTracker.update();
4077                try {
4078                    synchronized (processCpuTracker) {
4079                        processCpuTracker.wait(500); // measure over 1/2 second.
4080                    }
4081                } catch (InterruptedException e) {
4082                }
4083                processCpuTracker.update();
4084
4085                // We'll take the stack crawls of just the top apps using CPU.
4086                final int N = processCpuTracker.countWorkingStats();
4087                int numProcs = 0;
4088                for (int i=0; i<N && numProcs<5; i++) {
4089                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4090                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4091                        numProcs++;
4092                        try {
4093                            synchronized (observer) {
4094                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4095                                observer.wait(200);  // Wait for write-close, give up after 200msec
4096                            }
4097                        } catch (InterruptedException e) {
4098                            Log.wtf(TAG, e);
4099                        }
4100
4101                    }
4102                }
4103            }
4104        } finally {
4105            observer.stopWatching();
4106        }
4107    }
4108
4109    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4110        if (true || IS_USER_BUILD) {
4111            return;
4112        }
4113        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4114        if (tracesPath == null || tracesPath.length() == 0) {
4115            return;
4116        }
4117
4118        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4119        StrictMode.allowThreadDiskWrites();
4120        try {
4121            final File tracesFile = new File(tracesPath);
4122            final File tracesDir = tracesFile.getParentFile();
4123            final File tracesTmp = new File(tracesDir, "__tmp__");
4124            try {
4125                if (!tracesDir.exists()) {
4126                    tracesFile.mkdirs();
4127                    if (!SELinux.restorecon(tracesDir.getPath())) {
4128                        return;
4129                    }
4130                }
4131                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4132
4133                if (tracesFile.exists()) {
4134                    tracesTmp.delete();
4135                    tracesFile.renameTo(tracesTmp);
4136                }
4137                StringBuilder sb = new StringBuilder();
4138                Time tobj = new Time();
4139                tobj.set(System.currentTimeMillis());
4140                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4141                sb.append(": ");
4142                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4143                sb.append(" since ");
4144                sb.append(msg);
4145                FileOutputStream fos = new FileOutputStream(tracesFile);
4146                fos.write(sb.toString().getBytes());
4147                if (app == null) {
4148                    fos.write("\n*** No application process!".getBytes());
4149                }
4150                fos.close();
4151                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4152            } catch (IOException e) {
4153                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4154                return;
4155            }
4156
4157            if (app != null) {
4158                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4159                firstPids.add(app.pid);
4160                dumpStackTraces(tracesPath, firstPids, null, null, null);
4161            }
4162
4163            File lastTracesFile = null;
4164            File curTracesFile = null;
4165            for (int i=9; i>=0; i--) {
4166                String name = String.format(Locale.US, "slow%02d.txt", i);
4167                curTracesFile = new File(tracesDir, name);
4168                if (curTracesFile.exists()) {
4169                    if (lastTracesFile != null) {
4170                        curTracesFile.renameTo(lastTracesFile);
4171                    } else {
4172                        curTracesFile.delete();
4173                    }
4174                }
4175                lastTracesFile = curTracesFile;
4176            }
4177            tracesFile.renameTo(curTracesFile);
4178            if (tracesTmp.exists()) {
4179                tracesTmp.renameTo(tracesFile);
4180            }
4181        } finally {
4182            StrictMode.setThreadPolicy(oldPolicy);
4183        }
4184    }
4185
4186    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4187            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4188        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4189        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4190
4191        if (mController != null) {
4192            try {
4193                // 0 == continue, -1 = kill process immediately
4194                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4195                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4196            } catch (RemoteException e) {
4197                mController = null;
4198                Watchdog.getInstance().setActivityController(null);
4199            }
4200        }
4201
4202        long anrTime = SystemClock.uptimeMillis();
4203        if (MONITOR_CPU_USAGE) {
4204            updateCpuStatsNow();
4205        }
4206
4207        synchronized (this) {
4208            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4209            if (mShuttingDown) {
4210                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4211                return;
4212            } else if (app.notResponding) {
4213                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4214                return;
4215            } else if (app.crashing) {
4216                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4217                return;
4218            }
4219
4220            // In case we come through here for the same app before completing
4221            // this one, mark as anring now so we will bail out.
4222            app.notResponding = true;
4223
4224            // Log the ANR to the event log.
4225            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4226                    app.processName, app.info.flags, annotation);
4227
4228            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4229            firstPids.add(app.pid);
4230
4231            int parentPid = app.pid;
4232            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4233            if (parentPid != app.pid) firstPids.add(parentPid);
4234
4235            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4236
4237            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4238                ProcessRecord r = mLruProcesses.get(i);
4239                if (r != null && r.thread != null) {
4240                    int pid = r.pid;
4241                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4242                        if (r.persistent) {
4243                            firstPids.add(pid);
4244                        } else {
4245                            lastPids.put(pid, Boolean.TRUE);
4246                        }
4247                    }
4248                }
4249            }
4250        }
4251
4252        // Log the ANR to the main log.
4253        StringBuilder info = new StringBuilder();
4254        info.setLength(0);
4255        info.append("ANR in ").append(app.processName);
4256        if (activity != null && activity.shortComponentName != null) {
4257            info.append(" (").append(activity.shortComponentName).append(")");
4258        }
4259        info.append("\n");
4260        info.append("PID: ").append(app.pid).append("\n");
4261        if (annotation != null) {
4262            info.append("Reason: ").append(annotation).append("\n");
4263        }
4264        if (parent != null && parent != activity) {
4265            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4266        }
4267
4268        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4269
4270        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4271                NATIVE_STACKS_OF_INTEREST);
4272
4273        String cpuInfo = null;
4274        if (MONITOR_CPU_USAGE) {
4275            updateCpuStatsNow();
4276            synchronized (mProcessCpuThread) {
4277                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4278            }
4279            info.append(processCpuTracker.printCurrentLoad());
4280            info.append(cpuInfo);
4281        }
4282
4283        info.append(processCpuTracker.printCurrentState(anrTime));
4284
4285        Slog.e(TAG, info.toString());
4286        if (tracesFile == null) {
4287            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4288            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4289        }
4290
4291        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4292                cpuInfo, tracesFile, null);
4293
4294        if (mController != null) {
4295            try {
4296                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4297                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4298                if (res != 0) {
4299                    if (res < 0 && app.pid != MY_PID) {
4300                        Process.killProcess(app.pid);
4301                    } else {
4302                        synchronized (this) {
4303                            mServices.scheduleServiceTimeoutLocked(app);
4304                        }
4305                    }
4306                    return;
4307                }
4308            } catch (RemoteException e) {
4309                mController = null;
4310                Watchdog.getInstance().setActivityController(null);
4311            }
4312        }
4313
4314        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4315        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4316                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4317
4318        synchronized (this) {
4319            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4320                killUnneededProcessLocked(app, "background ANR");
4321                return;
4322            }
4323
4324            // Set the app's notResponding state, and look up the errorReportReceiver
4325            makeAppNotRespondingLocked(app,
4326                    activity != null ? activity.shortComponentName : null,
4327                    annotation != null ? "ANR " + annotation : "ANR",
4328                    info.toString());
4329
4330            // Bring up the infamous App Not Responding dialog
4331            Message msg = Message.obtain();
4332            HashMap<String, Object> map = new HashMap<String, Object>();
4333            msg.what = SHOW_NOT_RESPONDING_MSG;
4334            msg.obj = map;
4335            msg.arg1 = aboveSystem ? 1 : 0;
4336            map.put("app", app);
4337            if (activity != null) {
4338                map.put("activity", activity);
4339            }
4340
4341            mHandler.sendMessage(msg);
4342        }
4343    }
4344
4345    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4346        if (!mLaunchWarningShown) {
4347            mLaunchWarningShown = true;
4348            mHandler.post(new Runnable() {
4349                @Override
4350                public void run() {
4351                    synchronized (ActivityManagerService.this) {
4352                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4353                        d.show();
4354                        mHandler.postDelayed(new Runnable() {
4355                            @Override
4356                            public void run() {
4357                                synchronized (ActivityManagerService.this) {
4358                                    d.dismiss();
4359                                    mLaunchWarningShown = false;
4360                                }
4361                            }
4362                        }, 4000);
4363                    }
4364                }
4365            });
4366        }
4367    }
4368
4369    @Override
4370    public boolean clearApplicationUserData(final String packageName,
4371            final IPackageDataObserver observer, int userId) {
4372        enforceNotIsolatedCaller("clearApplicationUserData");
4373        int uid = Binder.getCallingUid();
4374        int pid = Binder.getCallingPid();
4375        userId = handleIncomingUser(pid, uid,
4376                userId, false, true, "clearApplicationUserData", null);
4377        long callingId = Binder.clearCallingIdentity();
4378        try {
4379            IPackageManager pm = AppGlobals.getPackageManager();
4380            int pkgUid = -1;
4381            synchronized(this) {
4382                try {
4383                    pkgUid = pm.getPackageUid(packageName, userId);
4384                } catch (RemoteException e) {
4385                }
4386                if (pkgUid == -1) {
4387                    Slog.w(TAG, "Invalid packageName: " + packageName);
4388                    if (observer != null) {
4389                        try {
4390                            observer.onRemoveCompleted(packageName, false);
4391                        } catch (RemoteException e) {
4392                            Slog.i(TAG, "Observer no longer exists.");
4393                        }
4394                    }
4395                    return false;
4396                }
4397                if (uid == pkgUid || checkComponentPermission(
4398                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4399                        pid, uid, -1, true)
4400                        == PackageManager.PERMISSION_GRANTED) {
4401                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4402                } else {
4403                    throw new SecurityException("PID " + pid + " does not have permission "
4404                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4405                                    + " of package " + packageName);
4406                }
4407            }
4408
4409            try {
4410                // Clear application user data
4411                pm.clearApplicationUserData(packageName, observer, userId);
4412
4413                // Remove all permissions granted from/to this package
4414                removeUriPermissionsForPackageLocked(packageName, userId, true);
4415
4416                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4417                        Uri.fromParts("package", packageName, null));
4418                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4419                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4420                        null, null, 0, null, null, null, false, false, userId);
4421            } catch (RemoteException e) {
4422            }
4423        } finally {
4424            Binder.restoreCallingIdentity(callingId);
4425        }
4426        return true;
4427    }
4428
4429    @Override
4430    public void killBackgroundProcesses(final String packageName, int userId) {
4431        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4432                != PackageManager.PERMISSION_GRANTED &&
4433                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4434                        != PackageManager.PERMISSION_GRANTED) {
4435            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4436                    + Binder.getCallingPid()
4437                    + ", uid=" + Binder.getCallingUid()
4438                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4439            Slog.w(TAG, msg);
4440            throw new SecurityException(msg);
4441        }
4442
4443        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4444                userId, true, true, "killBackgroundProcesses", null);
4445        long callingId = Binder.clearCallingIdentity();
4446        try {
4447            IPackageManager pm = AppGlobals.getPackageManager();
4448            synchronized(this) {
4449                int appId = -1;
4450                try {
4451                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4452                } catch (RemoteException e) {
4453                }
4454                if (appId == -1) {
4455                    Slog.w(TAG, "Invalid packageName: " + packageName);
4456                    return;
4457                }
4458                killPackageProcessesLocked(packageName, appId, userId,
4459                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4460            }
4461        } finally {
4462            Binder.restoreCallingIdentity(callingId);
4463        }
4464    }
4465
4466    @Override
4467    public void killAllBackgroundProcesses() {
4468        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4469                != PackageManager.PERMISSION_GRANTED) {
4470            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4471                    + Binder.getCallingPid()
4472                    + ", uid=" + Binder.getCallingUid()
4473                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4474            Slog.w(TAG, msg);
4475            throw new SecurityException(msg);
4476        }
4477
4478        long callingId = Binder.clearCallingIdentity();
4479        try {
4480            synchronized(this) {
4481                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4482                final int NP = mProcessNames.getMap().size();
4483                for (int ip=0; ip<NP; ip++) {
4484                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4485                    final int NA = apps.size();
4486                    for (int ia=0; ia<NA; ia++) {
4487                        ProcessRecord app = apps.valueAt(ia);
4488                        if (app.persistent) {
4489                            // we don't kill persistent processes
4490                            continue;
4491                        }
4492                        if (app.removed) {
4493                            procs.add(app);
4494                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4495                            app.removed = true;
4496                            procs.add(app);
4497                        }
4498                    }
4499                }
4500
4501                int N = procs.size();
4502                for (int i=0; i<N; i++) {
4503                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4504                }
4505                mAllowLowerMemLevel = true;
4506                updateOomAdjLocked();
4507                doLowMemReportIfNeededLocked(null);
4508            }
4509        } finally {
4510            Binder.restoreCallingIdentity(callingId);
4511        }
4512    }
4513
4514    @Override
4515    public void forceStopPackage(final String packageName, int userId) {
4516        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4517                != PackageManager.PERMISSION_GRANTED) {
4518            String msg = "Permission Denial: forceStopPackage() from pid="
4519                    + Binder.getCallingPid()
4520                    + ", uid=" + Binder.getCallingUid()
4521                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4522            Slog.w(TAG, msg);
4523            throw new SecurityException(msg);
4524        }
4525        final int callingPid = Binder.getCallingPid();
4526        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4527                userId, true, true, "forceStopPackage", null);
4528        long callingId = Binder.clearCallingIdentity();
4529        try {
4530            IPackageManager pm = AppGlobals.getPackageManager();
4531            synchronized(this) {
4532                int[] users = userId == UserHandle.USER_ALL
4533                        ? getUsersLocked() : new int[] { userId };
4534                for (int user : users) {
4535                    int pkgUid = -1;
4536                    try {
4537                        pkgUid = pm.getPackageUid(packageName, user);
4538                    } catch (RemoteException e) {
4539                    }
4540                    if (pkgUid == -1) {
4541                        Slog.w(TAG, "Invalid packageName: " + packageName);
4542                        continue;
4543                    }
4544                    try {
4545                        pm.setPackageStoppedState(packageName, true, user);
4546                    } catch (RemoteException e) {
4547                    } catch (IllegalArgumentException e) {
4548                        Slog.w(TAG, "Failed trying to unstop package "
4549                                + packageName + ": " + e);
4550                    }
4551                    if (isUserRunningLocked(user, false)) {
4552                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4553                    }
4554                }
4555            }
4556        } finally {
4557            Binder.restoreCallingIdentity(callingId);
4558        }
4559    }
4560
4561    /*
4562     * The pkg name and app id have to be specified.
4563     */
4564    @Override
4565    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4566        if (pkg == null) {
4567            return;
4568        }
4569        // Make sure the uid is valid.
4570        if (appid < 0) {
4571            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4572            return;
4573        }
4574        int callerUid = Binder.getCallingUid();
4575        // Only the system server can kill an application
4576        if (callerUid == Process.SYSTEM_UID) {
4577            // Post an aysnc message to kill the application
4578            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4579            msg.arg1 = appid;
4580            msg.arg2 = 0;
4581            Bundle bundle = new Bundle();
4582            bundle.putString("pkg", pkg);
4583            bundle.putString("reason", reason);
4584            msg.obj = bundle;
4585            mHandler.sendMessage(msg);
4586        } else {
4587            throw new SecurityException(callerUid + " cannot kill pkg: " +
4588                    pkg);
4589        }
4590    }
4591
4592    @Override
4593    public void closeSystemDialogs(String reason) {
4594        enforceNotIsolatedCaller("closeSystemDialogs");
4595
4596        final int pid = Binder.getCallingPid();
4597        final int uid = Binder.getCallingUid();
4598        final long origId = Binder.clearCallingIdentity();
4599        try {
4600            synchronized (this) {
4601                // Only allow this from foreground processes, so that background
4602                // applications can't abuse it to prevent system UI from being shown.
4603                if (uid >= Process.FIRST_APPLICATION_UID) {
4604                    ProcessRecord proc;
4605                    synchronized (mPidsSelfLocked) {
4606                        proc = mPidsSelfLocked.get(pid);
4607                    }
4608                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4609                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4610                                + " from background process " + proc);
4611                        return;
4612                    }
4613                }
4614                closeSystemDialogsLocked(reason);
4615            }
4616        } finally {
4617            Binder.restoreCallingIdentity(origId);
4618        }
4619    }
4620
4621    void closeSystemDialogsLocked(String reason) {
4622        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4623        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4624                | Intent.FLAG_RECEIVER_FOREGROUND);
4625        if (reason != null) {
4626            intent.putExtra("reason", reason);
4627        }
4628        mWindowManager.closeSystemDialogs(reason);
4629
4630        mStackSupervisor.closeSystemDialogsLocked();
4631
4632        broadcastIntentLocked(null, null, intent, null,
4633                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4634                Process.SYSTEM_UID, UserHandle.USER_ALL);
4635    }
4636
4637    @Override
4638    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4639        enforceNotIsolatedCaller("getProcessMemoryInfo");
4640        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4641        for (int i=pids.length-1; i>=0; i--) {
4642            ProcessRecord proc;
4643            int oomAdj;
4644            synchronized (this) {
4645                synchronized (mPidsSelfLocked) {
4646                    proc = mPidsSelfLocked.get(pids[i]);
4647                    oomAdj = proc != null ? proc.setAdj : 0;
4648                }
4649            }
4650            infos[i] = new Debug.MemoryInfo();
4651            Debug.getMemoryInfo(pids[i], infos[i]);
4652            if (proc != null) {
4653                synchronized (this) {
4654                    if (proc.thread != null && proc.setAdj == oomAdj) {
4655                        // Record this for posterity if the process has been stable.
4656                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4657                                infos[i].getTotalUss(), false, proc.pkgList);
4658                    }
4659                }
4660            }
4661        }
4662        return infos;
4663    }
4664
4665    @Override
4666    public long[] getProcessPss(int[] pids) {
4667        enforceNotIsolatedCaller("getProcessPss");
4668        long[] pss = new long[pids.length];
4669        for (int i=pids.length-1; i>=0; i--) {
4670            ProcessRecord proc;
4671            int oomAdj;
4672            synchronized (this) {
4673                synchronized (mPidsSelfLocked) {
4674                    proc = mPidsSelfLocked.get(pids[i]);
4675                    oomAdj = proc != null ? proc.setAdj : 0;
4676                }
4677            }
4678            long[] tmpUss = new long[1];
4679            pss[i] = Debug.getPss(pids[i], tmpUss);
4680            if (proc != null) {
4681                synchronized (this) {
4682                    if (proc.thread != null && proc.setAdj == oomAdj) {
4683                        // Record this for posterity if the process has been stable.
4684                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4685                    }
4686                }
4687            }
4688        }
4689        return pss;
4690    }
4691
4692    @Override
4693    public void killApplicationProcess(String processName, int uid) {
4694        if (processName == null) {
4695            return;
4696        }
4697
4698        int callerUid = Binder.getCallingUid();
4699        // Only the system server can kill an application
4700        if (callerUid == Process.SYSTEM_UID) {
4701            synchronized (this) {
4702                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4703                if (app != null && app.thread != null) {
4704                    try {
4705                        app.thread.scheduleSuicide();
4706                    } catch (RemoteException e) {
4707                        // If the other end already died, then our work here is done.
4708                    }
4709                } else {
4710                    Slog.w(TAG, "Process/uid not found attempting kill of "
4711                            + processName + " / " + uid);
4712                }
4713            }
4714        } else {
4715            throw new SecurityException(callerUid + " cannot kill app process: " +
4716                    processName);
4717        }
4718    }
4719
4720    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4721        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4722                false, true, false, false, UserHandle.getUserId(uid), reason);
4723        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4724                Uri.fromParts("package", packageName, null));
4725        if (!mProcessesReady) {
4726            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4727                    | Intent.FLAG_RECEIVER_FOREGROUND);
4728        }
4729        intent.putExtra(Intent.EXTRA_UID, uid);
4730        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4731        broadcastIntentLocked(null, null, intent,
4732                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4733                false, false,
4734                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4735    }
4736
4737    private void forceStopUserLocked(int userId, String reason) {
4738        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4739        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4740        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4741                | Intent.FLAG_RECEIVER_FOREGROUND);
4742        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4743        broadcastIntentLocked(null, null, intent,
4744                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4745                false, false,
4746                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4747    }
4748
4749    private final boolean killPackageProcessesLocked(String packageName, int appId,
4750            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4751            boolean doit, boolean evenPersistent, String reason) {
4752        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4753
4754        // Remove all processes this package may have touched: all with the
4755        // same UID (except for the system or root user), and all whose name
4756        // matches the package name.
4757        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4758        final int NP = mProcessNames.getMap().size();
4759        for (int ip=0; ip<NP; ip++) {
4760            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4761            final int NA = apps.size();
4762            for (int ia=0; ia<NA; ia++) {
4763                ProcessRecord app = apps.valueAt(ia);
4764                if (app.persistent && !evenPersistent) {
4765                    // we don't kill persistent processes
4766                    continue;
4767                }
4768                if (app.removed) {
4769                    if (doit) {
4770                        procs.add(app);
4771                    }
4772                    continue;
4773                }
4774
4775                // Skip process if it doesn't meet our oom adj requirement.
4776                if (app.setAdj < minOomAdj) {
4777                    continue;
4778                }
4779
4780                // If no package is specified, we call all processes under the
4781                // give user id.
4782                if (packageName == null) {
4783                    if (app.userId != userId) {
4784                        continue;
4785                    }
4786                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4787                        continue;
4788                    }
4789                // Package has been specified, we want to hit all processes
4790                // that match it.  We need to qualify this by the processes
4791                // that are running under the specified app and user ID.
4792                } else {
4793                    if (UserHandle.getAppId(app.uid) != appId) {
4794                        continue;
4795                    }
4796                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4797                        continue;
4798                    }
4799                    if (!app.pkgList.containsKey(packageName)) {
4800                        continue;
4801                    }
4802                }
4803
4804                // Process has passed all conditions, kill it!
4805                if (!doit) {
4806                    return true;
4807                }
4808                app.removed = true;
4809                procs.add(app);
4810            }
4811        }
4812
4813        int N = procs.size();
4814        for (int i=0; i<N; i++) {
4815            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4816        }
4817        updateOomAdjLocked();
4818        return N > 0;
4819    }
4820
4821    private final boolean forceStopPackageLocked(String name, int appId,
4822            boolean callerWillRestart, boolean purgeCache, boolean doit,
4823            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4824        int i;
4825        int N;
4826
4827        if (userId == UserHandle.USER_ALL && name == null) {
4828            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4829        }
4830
4831        if (appId < 0 && name != null) {
4832            try {
4833                appId = UserHandle.getAppId(
4834                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4835            } catch (RemoteException e) {
4836            }
4837        }
4838
4839        if (doit) {
4840            if (name != null) {
4841                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4842                        + " user=" + userId + ": " + reason);
4843            } else {
4844                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4845            }
4846
4847            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4848            for (int ip=pmap.size()-1; ip>=0; ip--) {
4849                SparseArray<Long> ba = pmap.valueAt(ip);
4850                for (i=ba.size()-1; i>=0; i--) {
4851                    boolean remove = false;
4852                    final int entUid = ba.keyAt(i);
4853                    if (name != null) {
4854                        if (userId == UserHandle.USER_ALL) {
4855                            if (UserHandle.getAppId(entUid) == appId) {
4856                                remove = true;
4857                            }
4858                        } else {
4859                            if (entUid == UserHandle.getUid(userId, appId)) {
4860                                remove = true;
4861                            }
4862                        }
4863                    } else if (UserHandle.getUserId(entUid) == userId) {
4864                        remove = true;
4865                    }
4866                    if (remove) {
4867                        ba.removeAt(i);
4868                    }
4869                }
4870                if (ba.size() == 0) {
4871                    pmap.removeAt(ip);
4872                }
4873            }
4874        }
4875
4876        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4877                -100, callerWillRestart, true, doit, evenPersistent,
4878                name == null ? ("stop user " + userId) : ("stop " + name));
4879
4880        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4881            if (!doit) {
4882                return true;
4883            }
4884            didSomething = true;
4885        }
4886
4887        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4888            if (!doit) {
4889                return true;
4890            }
4891            didSomething = true;
4892        }
4893
4894        if (name == null) {
4895            // Remove all sticky broadcasts from this user.
4896            mStickyBroadcasts.remove(userId);
4897        }
4898
4899        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4900        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4901                userId, providers)) {
4902            if (!doit) {
4903                return true;
4904            }
4905            didSomething = true;
4906        }
4907        N = providers.size();
4908        for (i=0; i<N; i++) {
4909            removeDyingProviderLocked(null, providers.get(i), true);
4910        }
4911
4912        // Remove transient permissions granted from/to this package/user
4913        removeUriPermissionsForPackageLocked(name, userId, false);
4914
4915        if (name == null || uninstalling) {
4916            // Remove pending intents.  For now we only do this when force
4917            // stopping users, because we have some problems when doing this
4918            // for packages -- app widgets are not currently cleaned up for
4919            // such packages, so they can be left with bad pending intents.
4920            if (mIntentSenderRecords.size() > 0) {
4921                Iterator<WeakReference<PendingIntentRecord>> it
4922                        = mIntentSenderRecords.values().iterator();
4923                while (it.hasNext()) {
4924                    WeakReference<PendingIntentRecord> wpir = it.next();
4925                    if (wpir == null) {
4926                        it.remove();
4927                        continue;
4928                    }
4929                    PendingIntentRecord pir = wpir.get();
4930                    if (pir == null) {
4931                        it.remove();
4932                        continue;
4933                    }
4934                    if (name == null) {
4935                        // Stopping user, remove all objects for the user.
4936                        if (pir.key.userId != userId) {
4937                            // Not the same user, skip it.
4938                            continue;
4939                        }
4940                    } else {
4941                        if (UserHandle.getAppId(pir.uid) != appId) {
4942                            // Different app id, skip it.
4943                            continue;
4944                        }
4945                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4946                            // Different user, skip it.
4947                            continue;
4948                        }
4949                        if (!pir.key.packageName.equals(name)) {
4950                            // Different package, skip it.
4951                            continue;
4952                        }
4953                    }
4954                    if (!doit) {
4955                        return true;
4956                    }
4957                    didSomething = true;
4958                    it.remove();
4959                    pir.canceled = true;
4960                    if (pir.key.activity != null) {
4961                        pir.key.activity.pendingResults.remove(pir.ref);
4962                    }
4963                }
4964            }
4965        }
4966
4967        if (doit) {
4968            if (purgeCache && name != null) {
4969                AttributeCache ac = AttributeCache.instance();
4970                if (ac != null) {
4971                    ac.removePackage(name);
4972                }
4973            }
4974            if (mBooted) {
4975                mStackSupervisor.resumeTopActivitiesLocked();
4976                mStackSupervisor.scheduleIdleLocked();
4977            }
4978        }
4979
4980        return didSomething;
4981    }
4982
4983    private final boolean removeProcessLocked(ProcessRecord app,
4984            boolean callerWillRestart, boolean allowRestart, String reason) {
4985        final String name = app.processName;
4986        final int uid = app.uid;
4987        if (DEBUG_PROCESSES) Slog.d(
4988            TAG, "Force removing proc " + app.toShortString() + " (" + name
4989            + "/" + uid + ")");
4990
4991        mProcessNames.remove(name, uid);
4992        mIsolatedProcesses.remove(app.uid);
4993        if (mHeavyWeightProcess == app) {
4994            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4995                    mHeavyWeightProcess.userId, 0));
4996            mHeavyWeightProcess = null;
4997        }
4998        boolean needRestart = false;
4999        if (app.pid > 0 && app.pid != MY_PID) {
5000            int pid = app.pid;
5001            synchronized (mPidsSelfLocked) {
5002                mPidsSelfLocked.remove(pid);
5003                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5004            }
5005            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5006                    app.processName, app.info.uid);
5007            if (app.isolated) {
5008                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5009            }
5010            killUnneededProcessLocked(app, reason);
5011            handleAppDiedLocked(app, true, allowRestart);
5012            removeLruProcessLocked(app);
5013
5014            if (app.persistent && !app.isolated) {
5015                if (!callerWillRestart) {
5016                    addAppLocked(app.info, false);
5017                } else {
5018                    needRestart = true;
5019                }
5020            }
5021        } else {
5022            mRemovedProcesses.add(app);
5023        }
5024
5025        return needRestart;
5026    }
5027
5028    private final void processStartTimedOutLocked(ProcessRecord app) {
5029        final int pid = app.pid;
5030        boolean gone = false;
5031        synchronized (mPidsSelfLocked) {
5032            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5033            if (knownApp != null && knownApp.thread == null) {
5034                mPidsSelfLocked.remove(pid);
5035                gone = true;
5036            }
5037        }
5038
5039        if (gone) {
5040            Slog.w(TAG, "Process " + app + " failed to attach");
5041            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5042                    pid, app.uid, app.processName);
5043            mProcessNames.remove(app.processName, app.uid);
5044            mIsolatedProcesses.remove(app.uid);
5045            if (mHeavyWeightProcess == app) {
5046                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5047                        mHeavyWeightProcess.userId, 0));
5048                mHeavyWeightProcess = null;
5049            }
5050            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5051                    app.processName, app.info.uid);
5052            if (app.isolated) {
5053                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5054            }
5055            // Take care of any launching providers waiting for this process.
5056            checkAppInLaunchingProvidersLocked(app, true);
5057            // Take care of any services that are waiting for the process.
5058            mServices.processStartTimedOutLocked(app);
5059            killUnneededProcessLocked(app, "start timeout");
5060            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5061                Slog.w(TAG, "Unattached app died before backup, skipping");
5062                try {
5063                    IBackupManager bm = IBackupManager.Stub.asInterface(
5064                            ServiceManager.getService(Context.BACKUP_SERVICE));
5065                    bm.agentDisconnected(app.info.packageName);
5066                } catch (RemoteException e) {
5067                    // Can't happen; the backup manager is local
5068                }
5069            }
5070            if (isPendingBroadcastProcessLocked(pid)) {
5071                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5072                skipPendingBroadcastLocked(pid);
5073            }
5074        } else {
5075            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5076        }
5077    }
5078
5079    private final boolean attachApplicationLocked(IApplicationThread thread,
5080            int pid) {
5081
5082        // Find the application record that is being attached...  either via
5083        // the pid if we are running in multiple processes, or just pull the
5084        // next app record if we are emulating process with anonymous threads.
5085        ProcessRecord app;
5086        if (pid != MY_PID && pid >= 0) {
5087            synchronized (mPidsSelfLocked) {
5088                app = mPidsSelfLocked.get(pid);
5089            }
5090        } else {
5091            app = null;
5092        }
5093
5094        if (app == null) {
5095            Slog.w(TAG, "No pending application record for pid " + pid
5096                    + " (IApplicationThread " + thread + "); dropping process");
5097            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5098            if (pid > 0 && pid != MY_PID) {
5099                Process.killProcessQuiet(pid);
5100            } else {
5101                try {
5102                    thread.scheduleExit();
5103                } catch (Exception e) {
5104                    // Ignore exceptions.
5105                }
5106            }
5107            return false;
5108        }
5109
5110        // If this application record is still attached to a previous
5111        // process, clean it up now.
5112        if (app.thread != null) {
5113            handleAppDiedLocked(app, true, true);
5114        }
5115
5116        // Tell the process all about itself.
5117
5118        if (localLOGV) Slog.v(
5119                TAG, "Binding process pid " + pid + " to record " + app);
5120
5121        final String processName = app.processName;
5122        try {
5123            AppDeathRecipient adr = new AppDeathRecipient(
5124                    app, pid, thread);
5125            thread.asBinder().linkToDeath(adr, 0);
5126            app.deathRecipient = adr;
5127        } catch (RemoteException e) {
5128            app.resetPackageList(mProcessStats);
5129            startProcessLocked(app, "link fail", processName);
5130            return false;
5131        }
5132
5133        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5134
5135        app.makeActive(thread, mProcessStats);
5136        app.curAdj = app.setAdj = -100;
5137        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5138        app.forcingToForeground = null;
5139        updateProcessForegroundLocked(app, false, false);
5140        app.hasShownUi = false;
5141        app.debugging = false;
5142        app.cached = false;
5143
5144        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5145
5146        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5147        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5148
5149        if (!normalMode) {
5150            Slog.i(TAG, "Launching preboot mode app: " + app);
5151        }
5152
5153        if (localLOGV) Slog.v(
5154            TAG, "New app record " + app
5155            + " thread=" + thread.asBinder() + " pid=" + pid);
5156        try {
5157            int testMode = IApplicationThread.DEBUG_OFF;
5158            if (mDebugApp != null && mDebugApp.equals(processName)) {
5159                testMode = mWaitForDebugger
5160                    ? IApplicationThread.DEBUG_WAIT
5161                    : IApplicationThread.DEBUG_ON;
5162                app.debugging = true;
5163                if (mDebugTransient) {
5164                    mDebugApp = mOrigDebugApp;
5165                    mWaitForDebugger = mOrigWaitForDebugger;
5166                }
5167            }
5168            String profileFile = app.instrumentationProfileFile;
5169            ParcelFileDescriptor profileFd = null;
5170            boolean profileAutoStop = false;
5171            if (mProfileApp != null && mProfileApp.equals(processName)) {
5172                mProfileProc = app;
5173                profileFile = mProfileFile;
5174                profileFd = mProfileFd;
5175                profileAutoStop = mAutoStopProfiler;
5176            }
5177            boolean enableOpenGlTrace = false;
5178            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5179                enableOpenGlTrace = true;
5180                mOpenGlTraceApp = null;
5181            }
5182
5183            // If the app is being launched for restore or full backup, set it up specially
5184            boolean isRestrictedBackupMode = false;
5185            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5186                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5187                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5188                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5189            }
5190
5191            ensurePackageDexOpt(app.instrumentationInfo != null
5192                    ? app.instrumentationInfo.packageName
5193                    : app.info.packageName);
5194            if (app.instrumentationClass != null) {
5195                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5196            }
5197            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5198                    + processName + " with config " + mConfiguration);
5199            ApplicationInfo appInfo = app.instrumentationInfo != null
5200                    ? app.instrumentationInfo : app.info;
5201            app.compat = compatibilityInfoForPackageLocked(appInfo);
5202            if (profileFd != null) {
5203                profileFd = profileFd.dup();
5204            }
5205            thread.bindApplication(processName, appInfo, providers,
5206                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5207                    app.instrumentationArguments, app.instrumentationWatcher,
5208                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5209                    isRestrictedBackupMode || !normalMode, app.persistent,
5210                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5211                    mCoreSettingsObserver.getCoreSettingsLocked());
5212            updateLruProcessLocked(app, false, null);
5213            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5214        } catch (Exception e) {
5215            // todo: Yikes!  What should we do?  For now we will try to
5216            // start another process, but that could easily get us in
5217            // an infinite loop of restarting processes...
5218            Slog.w(TAG, "Exception thrown during bind!", e);
5219
5220            app.resetPackageList(mProcessStats);
5221            app.unlinkDeathRecipient();
5222            startProcessLocked(app, "bind fail", processName);
5223            return false;
5224        }
5225
5226        // Remove this record from the list of starting applications.
5227        mPersistentStartingProcesses.remove(app);
5228        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5229                "Attach application locked removing on hold: " + app);
5230        mProcessesOnHold.remove(app);
5231
5232        boolean badApp = false;
5233        boolean didSomething = false;
5234
5235        // See if the top visible activity is waiting to run in this process...
5236        if (normalMode) {
5237            try {
5238                if (mStackSupervisor.attachApplicationLocked(app)) {
5239                    didSomething = true;
5240                }
5241            } catch (Exception e) {
5242                badApp = true;
5243            }
5244        }
5245
5246        // Find any services that should be running in this process...
5247        if (!badApp) {
5248            try {
5249                didSomething |= mServices.attachApplicationLocked(app, processName);
5250            } catch (Exception e) {
5251                badApp = true;
5252            }
5253        }
5254
5255        // Check if a next-broadcast receiver is in this process...
5256        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5257            try {
5258                didSomething |= sendPendingBroadcastsLocked(app);
5259            } catch (Exception e) {
5260                // If the app died trying to launch the receiver we declare it 'bad'
5261                badApp = true;
5262            }
5263        }
5264
5265        // Check whether the next backup agent is in this process...
5266        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5267            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5268            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5269            try {
5270                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5271                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5272                        mBackupTarget.backupMode);
5273            } catch (Exception e) {
5274                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5275                e.printStackTrace();
5276            }
5277        }
5278
5279        if (badApp) {
5280            // todo: Also need to kill application to deal with all
5281            // kinds of exceptions.
5282            handleAppDiedLocked(app, false, true);
5283            return false;
5284        }
5285
5286        if (!didSomething) {
5287            updateOomAdjLocked();
5288        }
5289
5290        return true;
5291    }
5292
5293    @Override
5294    public final void attachApplication(IApplicationThread thread) {
5295        synchronized (this) {
5296            int callingPid = Binder.getCallingPid();
5297            final long origId = Binder.clearCallingIdentity();
5298            attachApplicationLocked(thread, callingPid);
5299            Binder.restoreCallingIdentity(origId);
5300        }
5301    }
5302
5303    @Override
5304    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5305        final long origId = Binder.clearCallingIdentity();
5306        synchronized (this) {
5307            ActivityStack stack = ActivityRecord.getStackLocked(token);
5308            if (stack != null) {
5309                ActivityRecord r =
5310                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5311                if (stopProfiling) {
5312                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5313                        try {
5314                            mProfileFd.close();
5315                        } catch (IOException e) {
5316                        }
5317                        clearProfilerLocked();
5318                    }
5319                }
5320            }
5321        }
5322        Binder.restoreCallingIdentity(origId);
5323    }
5324
5325    void enableScreenAfterBoot() {
5326        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5327                SystemClock.uptimeMillis());
5328        mWindowManager.enableScreenAfterBoot();
5329
5330        synchronized (this) {
5331            updateEventDispatchingLocked();
5332        }
5333    }
5334
5335    @Override
5336    public void showBootMessage(final CharSequence msg, final boolean always) {
5337        enforceNotIsolatedCaller("showBootMessage");
5338        mWindowManager.showBootMessage(msg, always);
5339    }
5340
5341    @Override
5342    public void dismissKeyguardOnNextActivity() {
5343        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5344        final long token = Binder.clearCallingIdentity();
5345        try {
5346            synchronized (this) {
5347                if (DEBUG_LOCKSCREEN) logLockScreen("");
5348                if (mLockScreenShown) {
5349                    mLockScreenShown = false;
5350                    comeOutOfSleepIfNeededLocked();
5351                }
5352                mStackSupervisor.setDismissKeyguard(true);
5353            }
5354        } finally {
5355            Binder.restoreCallingIdentity(token);
5356        }
5357    }
5358
5359    final void finishBooting() {
5360        // Register receivers to handle package update events
5361        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5362
5363        synchronized (this) {
5364            // Ensure that any processes we had put on hold are now started
5365            // up.
5366            final int NP = mProcessesOnHold.size();
5367            if (NP > 0) {
5368                ArrayList<ProcessRecord> procs =
5369                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5370                for (int ip=0; ip<NP; ip++) {
5371                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5372                            + procs.get(ip));
5373                    startProcessLocked(procs.get(ip), "on-hold", null);
5374                }
5375            }
5376
5377            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5378                // Start looking for apps that are abusing wake locks.
5379                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5380                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5381                // Tell anyone interested that we are done booting!
5382                SystemProperties.set("sys.boot_completed", "1");
5383                SystemProperties.set("dev.bootcomplete", "1");
5384                for (int i=0; i<mStartedUsers.size(); i++) {
5385                    UserStartedState uss = mStartedUsers.valueAt(i);
5386                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5387                        uss.mState = UserStartedState.STATE_RUNNING;
5388                        final int userId = mStartedUsers.keyAt(i);
5389                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5390                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5391                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5392                        broadcastIntentLocked(null, null, intent, null,
5393                                new IIntentReceiver.Stub() {
5394                                    @Override
5395                                    public void performReceive(Intent intent, int resultCode,
5396                                            String data, Bundle extras, boolean ordered,
5397                                            boolean sticky, int sendingUser) {
5398                                        synchronized (ActivityManagerService.this) {
5399                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5400                                                    true, false);
5401                                        }
5402                                    }
5403                                },
5404                                0, null, null,
5405                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5406                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5407                                userId);
5408                    }
5409                }
5410                scheduleStartProfilesLocked();
5411            }
5412        }
5413    }
5414
5415    final void ensureBootCompleted() {
5416        boolean booting;
5417        boolean enableScreen;
5418        synchronized (this) {
5419            booting = mBooting;
5420            mBooting = false;
5421            enableScreen = !mBooted;
5422            mBooted = true;
5423        }
5424
5425        if (booting) {
5426            finishBooting();
5427        }
5428
5429        if (enableScreen) {
5430            enableScreenAfterBoot();
5431        }
5432    }
5433
5434    @Override
5435    public final void activityResumed(IBinder token) {
5436        final long origId = Binder.clearCallingIdentity();
5437        synchronized(this) {
5438            ActivityStack stack = ActivityRecord.getStackLocked(token);
5439            if (stack != null) {
5440                ActivityRecord.activityResumedLocked(token);
5441            }
5442        }
5443        Binder.restoreCallingIdentity(origId);
5444    }
5445
5446    @Override
5447    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5448        final long origId = Binder.clearCallingIdentity();
5449        synchronized(this) {
5450            ActivityStack stack = ActivityRecord.getStackLocked(token);
5451            if (stack != null) {
5452                stack.activityPausedLocked(token, false, persistentState);
5453            }
5454        }
5455        Binder.restoreCallingIdentity(origId);
5456    }
5457
5458    @Override
5459    public final void activityStopped(IBinder token, Bundle icicle,
5460            PersistableBundle persistentState, CharSequence description) {
5461        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5462
5463        // Refuse possible leaked file descriptors
5464        if (icicle != null && icicle.hasFileDescriptors()) {
5465            throw new IllegalArgumentException("File descriptors passed in Bundle");
5466        }
5467
5468        final long origId = Binder.clearCallingIdentity();
5469
5470        synchronized (this) {
5471            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5472            if (r != null) {
5473                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5474            }
5475        }
5476
5477        trimApplications();
5478
5479        Binder.restoreCallingIdentity(origId);
5480    }
5481
5482    @Override
5483    public final void activityDestroyed(IBinder token) {
5484        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5485        synchronized (this) {
5486            ActivityStack stack = ActivityRecord.getStackLocked(token);
5487            if (stack != null) {
5488                stack.activityDestroyedLocked(token);
5489            }
5490        }
5491    }
5492
5493    @Override
5494    public String getCallingPackage(IBinder token) {
5495        synchronized (this) {
5496            ActivityRecord r = getCallingRecordLocked(token);
5497            return r != null ? r.info.packageName : null;
5498        }
5499    }
5500
5501    @Override
5502    public ComponentName getCallingActivity(IBinder token) {
5503        synchronized (this) {
5504            ActivityRecord r = getCallingRecordLocked(token);
5505            return r != null ? r.intent.getComponent() : null;
5506        }
5507    }
5508
5509    private ActivityRecord getCallingRecordLocked(IBinder token) {
5510        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5511        if (r == null) {
5512            return null;
5513        }
5514        return r.resultTo;
5515    }
5516
5517    @Override
5518    public ComponentName getActivityClassForToken(IBinder token) {
5519        synchronized(this) {
5520            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5521            if (r == null) {
5522                return null;
5523            }
5524            return r.intent.getComponent();
5525        }
5526    }
5527
5528    @Override
5529    public String getPackageForToken(IBinder token) {
5530        synchronized(this) {
5531            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5532            if (r == null) {
5533                return null;
5534            }
5535            return r.packageName;
5536        }
5537    }
5538
5539    @Override
5540    public IIntentSender getIntentSender(int type,
5541            String packageName, IBinder token, String resultWho,
5542            int requestCode, Intent[] intents, String[] resolvedTypes,
5543            int flags, Bundle options, int userId) {
5544        enforceNotIsolatedCaller("getIntentSender");
5545        // Refuse possible leaked file descriptors
5546        if (intents != null) {
5547            if (intents.length < 1) {
5548                throw new IllegalArgumentException("Intents array length must be >= 1");
5549            }
5550            for (int i=0; i<intents.length; i++) {
5551                Intent intent = intents[i];
5552                if (intent != null) {
5553                    if (intent.hasFileDescriptors()) {
5554                        throw new IllegalArgumentException("File descriptors passed in Intent");
5555                    }
5556                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5557                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5558                        throw new IllegalArgumentException(
5559                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5560                    }
5561                    intents[i] = new Intent(intent);
5562                }
5563            }
5564            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5565                throw new IllegalArgumentException(
5566                        "Intent array length does not match resolvedTypes length");
5567            }
5568        }
5569        if (options != null) {
5570            if (options.hasFileDescriptors()) {
5571                throw new IllegalArgumentException("File descriptors passed in options");
5572            }
5573        }
5574
5575        synchronized(this) {
5576            int callingUid = Binder.getCallingUid();
5577            int origUserId = userId;
5578            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5579                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5580                    "getIntentSender", null);
5581            if (origUserId == UserHandle.USER_CURRENT) {
5582                // We don't want to evaluate this until the pending intent is
5583                // actually executed.  However, we do want to always do the
5584                // security checking for it above.
5585                userId = UserHandle.USER_CURRENT;
5586            }
5587            try {
5588                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5589                    int uid = AppGlobals.getPackageManager()
5590                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5591                    if (!UserHandle.isSameApp(callingUid, uid)) {
5592                        String msg = "Permission Denial: getIntentSender() from pid="
5593                            + Binder.getCallingPid()
5594                            + ", uid=" + Binder.getCallingUid()
5595                            + ", (need uid=" + uid + ")"
5596                            + " is not allowed to send as package " + packageName;
5597                        Slog.w(TAG, msg);
5598                        throw new SecurityException(msg);
5599                    }
5600                }
5601
5602                return getIntentSenderLocked(type, packageName, callingUid, userId,
5603                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5604
5605            } catch (RemoteException e) {
5606                throw new SecurityException(e);
5607            }
5608        }
5609    }
5610
5611    IIntentSender getIntentSenderLocked(int type, String packageName,
5612            int callingUid, int userId, IBinder token, String resultWho,
5613            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5614            Bundle options) {
5615        if (DEBUG_MU)
5616            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5617        ActivityRecord activity = null;
5618        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5619            activity = ActivityRecord.isInStackLocked(token);
5620            if (activity == null) {
5621                return null;
5622            }
5623            if (activity.finishing) {
5624                return null;
5625            }
5626        }
5627
5628        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5629        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5630        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5631        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5632                |PendingIntent.FLAG_UPDATE_CURRENT);
5633
5634        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5635                type, packageName, activity, resultWho,
5636                requestCode, intents, resolvedTypes, flags, options, userId);
5637        WeakReference<PendingIntentRecord> ref;
5638        ref = mIntentSenderRecords.get(key);
5639        PendingIntentRecord rec = ref != null ? ref.get() : null;
5640        if (rec != null) {
5641            if (!cancelCurrent) {
5642                if (updateCurrent) {
5643                    if (rec.key.requestIntent != null) {
5644                        rec.key.requestIntent.replaceExtras(intents != null ?
5645                                intents[intents.length - 1] : null);
5646                    }
5647                    if (intents != null) {
5648                        intents[intents.length-1] = rec.key.requestIntent;
5649                        rec.key.allIntents = intents;
5650                        rec.key.allResolvedTypes = resolvedTypes;
5651                    } else {
5652                        rec.key.allIntents = null;
5653                        rec.key.allResolvedTypes = null;
5654                    }
5655                }
5656                return rec;
5657            }
5658            rec.canceled = true;
5659            mIntentSenderRecords.remove(key);
5660        }
5661        if (noCreate) {
5662            return rec;
5663        }
5664        rec = new PendingIntentRecord(this, key, callingUid);
5665        mIntentSenderRecords.put(key, rec.ref);
5666        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5667            if (activity.pendingResults == null) {
5668                activity.pendingResults
5669                        = new HashSet<WeakReference<PendingIntentRecord>>();
5670            }
5671            activity.pendingResults.add(rec.ref);
5672        }
5673        return rec;
5674    }
5675
5676    @Override
5677    public void cancelIntentSender(IIntentSender sender) {
5678        if (!(sender instanceof PendingIntentRecord)) {
5679            return;
5680        }
5681        synchronized(this) {
5682            PendingIntentRecord rec = (PendingIntentRecord)sender;
5683            try {
5684                int uid = AppGlobals.getPackageManager()
5685                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5686                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5687                    String msg = "Permission Denial: cancelIntentSender() from pid="
5688                        + Binder.getCallingPid()
5689                        + ", uid=" + Binder.getCallingUid()
5690                        + " is not allowed to cancel packges "
5691                        + rec.key.packageName;
5692                    Slog.w(TAG, msg);
5693                    throw new SecurityException(msg);
5694                }
5695            } catch (RemoteException e) {
5696                throw new SecurityException(e);
5697            }
5698            cancelIntentSenderLocked(rec, true);
5699        }
5700    }
5701
5702    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5703        rec.canceled = true;
5704        mIntentSenderRecords.remove(rec.key);
5705        if (cleanActivity && rec.key.activity != null) {
5706            rec.key.activity.pendingResults.remove(rec.ref);
5707        }
5708    }
5709
5710    @Override
5711    public String getPackageForIntentSender(IIntentSender pendingResult) {
5712        if (!(pendingResult instanceof PendingIntentRecord)) {
5713            return null;
5714        }
5715        try {
5716            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5717            return res.key.packageName;
5718        } catch (ClassCastException e) {
5719        }
5720        return null;
5721    }
5722
5723    @Override
5724    public int getUidForIntentSender(IIntentSender sender) {
5725        if (sender instanceof PendingIntentRecord) {
5726            try {
5727                PendingIntentRecord res = (PendingIntentRecord)sender;
5728                return res.uid;
5729            } catch (ClassCastException e) {
5730            }
5731        }
5732        return -1;
5733    }
5734
5735    @Override
5736    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5737        if (!(pendingResult instanceof PendingIntentRecord)) {
5738            return false;
5739        }
5740        try {
5741            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5742            if (res.key.allIntents == null) {
5743                return false;
5744            }
5745            for (int i=0; i<res.key.allIntents.length; i++) {
5746                Intent intent = res.key.allIntents[i];
5747                if (intent.getPackage() != null && intent.getComponent() != null) {
5748                    return false;
5749                }
5750            }
5751            return true;
5752        } catch (ClassCastException e) {
5753        }
5754        return false;
5755    }
5756
5757    @Override
5758    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5759        if (!(pendingResult instanceof PendingIntentRecord)) {
5760            return false;
5761        }
5762        try {
5763            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5764            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5765                return true;
5766            }
5767            return false;
5768        } catch (ClassCastException e) {
5769        }
5770        return false;
5771    }
5772
5773    @Override
5774    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5775        if (!(pendingResult instanceof PendingIntentRecord)) {
5776            return null;
5777        }
5778        try {
5779            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5780            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5781        } catch (ClassCastException e) {
5782        }
5783        return null;
5784    }
5785
5786    @Override
5787    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5788        if (!(pendingResult instanceof PendingIntentRecord)) {
5789            return null;
5790        }
5791        try {
5792            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5793            Intent intent = res.key.requestIntent;
5794            if (intent != null) {
5795                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5796                        || res.lastTagPrefix.equals(prefix))) {
5797                    return res.lastTag;
5798                }
5799                res.lastTagPrefix = prefix;
5800                StringBuilder sb = new StringBuilder(128);
5801                if (prefix != null) {
5802                    sb.append(prefix);
5803                }
5804                if (intent.getAction() != null) {
5805                    sb.append(intent.getAction());
5806                } else if (intent.getComponent() != null) {
5807                    intent.getComponent().appendShortString(sb);
5808                } else {
5809                    sb.append("?");
5810                }
5811                return res.lastTag = sb.toString();
5812            }
5813        } catch (ClassCastException e) {
5814        }
5815        return null;
5816    }
5817
5818    @Override
5819    public void setProcessLimit(int max) {
5820        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5821                "setProcessLimit()");
5822        synchronized (this) {
5823            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5824            mProcessLimitOverride = max;
5825        }
5826        trimApplications();
5827    }
5828
5829    @Override
5830    public int getProcessLimit() {
5831        synchronized (this) {
5832            return mProcessLimitOverride;
5833        }
5834    }
5835
5836    void foregroundTokenDied(ForegroundToken token) {
5837        synchronized (ActivityManagerService.this) {
5838            synchronized (mPidsSelfLocked) {
5839                ForegroundToken cur
5840                    = mForegroundProcesses.get(token.pid);
5841                if (cur != token) {
5842                    return;
5843                }
5844                mForegroundProcesses.remove(token.pid);
5845                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5846                if (pr == null) {
5847                    return;
5848                }
5849                pr.forcingToForeground = null;
5850                updateProcessForegroundLocked(pr, false, false);
5851            }
5852            updateOomAdjLocked();
5853        }
5854    }
5855
5856    @Override
5857    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5858        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5859                "setProcessForeground()");
5860        synchronized(this) {
5861            boolean changed = false;
5862
5863            synchronized (mPidsSelfLocked) {
5864                ProcessRecord pr = mPidsSelfLocked.get(pid);
5865                if (pr == null && isForeground) {
5866                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5867                    return;
5868                }
5869                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5870                if (oldToken != null) {
5871                    oldToken.token.unlinkToDeath(oldToken, 0);
5872                    mForegroundProcesses.remove(pid);
5873                    if (pr != null) {
5874                        pr.forcingToForeground = null;
5875                    }
5876                    changed = true;
5877                }
5878                if (isForeground && token != null) {
5879                    ForegroundToken newToken = new ForegroundToken() {
5880                        @Override
5881                        public void binderDied() {
5882                            foregroundTokenDied(this);
5883                        }
5884                    };
5885                    newToken.pid = pid;
5886                    newToken.token = token;
5887                    try {
5888                        token.linkToDeath(newToken, 0);
5889                        mForegroundProcesses.put(pid, newToken);
5890                        pr.forcingToForeground = token;
5891                        changed = true;
5892                    } catch (RemoteException e) {
5893                        // If the process died while doing this, we will later
5894                        // do the cleanup with the process death link.
5895                    }
5896                }
5897            }
5898
5899            if (changed) {
5900                updateOomAdjLocked();
5901            }
5902        }
5903    }
5904
5905    // =========================================================
5906    // PERMISSIONS
5907    // =========================================================
5908
5909    static class PermissionController extends IPermissionController.Stub {
5910        ActivityManagerService mActivityManagerService;
5911        PermissionController(ActivityManagerService activityManagerService) {
5912            mActivityManagerService = activityManagerService;
5913        }
5914
5915        @Override
5916        public boolean checkPermission(String permission, int pid, int uid) {
5917            return mActivityManagerService.checkPermission(permission, pid,
5918                    uid) == PackageManager.PERMISSION_GRANTED;
5919        }
5920    }
5921
5922    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5923        @Override
5924        public int checkComponentPermission(String permission, int pid, int uid,
5925                int owningUid, boolean exported) {
5926            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5927                    owningUid, exported);
5928        }
5929
5930        @Override
5931        public Object getAMSLock() {
5932            return ActivityManagerService.this;
5933        }
5934    }
5935
5936    /**
5937     * This can be called with or without the global lock held.
5938     */
5939    int checkComponentPermission(String permission, int pid, int uid,
5940            int owningUid, boolean exported) {
5941        // We might be performing an operation on behalf of an indirect binder
5942        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5943        // client identity accordingly before proceeding.
5944        Identity tlsIdentity = sCallerIdentity.get();
5945        if (tlsIdentity != null) {
5946            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5947                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5948            uid = tlsIdentity.uid;
5949            pid = tlsIdentity.pid;
5950        }
5951
5952        if (pid == MY_PID) {
5953            return PackageManager.PERMISSION_GRANTED;
5954        }
5955
5956        return ActivityManager.checkComponentPermission(permission, uid,
5957                owningUid, exported);
5958    }
5959
5960    /**
5961     * As the only public entry point for permissions checking, this method
5962     * can enforce the semantic that requesting a check on a null global
5963     * permission is automatically denied.  (Internally a null permission
5964     * string is used when calling {@link #checkComponentPermission} in cases
5965     * when only uid-based security is needed.)
5966     *
5967     * This can be called with or without the global lock held.
5968     */
5969    @Override
5970    public int checkPermission(String permission, int pid, int uid) {
5971        if (permission == null) {
5972            return PackageManager.PERMISSION_DENIED;
5973        }
5974        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5975    }
5976
5977    /**
5978     * Binder IPC calls go through the public entry point.
5979     * This can be called with or without the global lock held.
5980     */
5981    int checkCallingPermission(String permission) {
5982        return checkPermission(permission,
5983                Binder.getCallingPid(),
5984                UserHandle.getAppId(Binder.getCallingUid()));
5985    }
5986
5987    /**
5988     * This can be called with or without the global lock held.
5989     */
5990    void enforceCallingPermission(String permission, String func) {
5991        if (checkCallingPermission(permission)
5992                == PackageManager.PERMISSION_GRANTED) {
5993            return;
5994        }
5995
5996        String msg = "Permission Denial: " + func + " from pid="
5997                + Binder.getCallingPid()
5998                + ", uid=" + Binder.getCallingUid()
5999                + " requires " + permission;
6000        Slog.w(TAG, msg);
6001        throw new SecurityException(msg);
6002    }
6003
6004    /**
6005     * Determine if UID is holding permissions required to access {@link Uri} in
6006     * the given {@link ProviderInfo}. Final permission checking is always done
6007     * in {@link ContentProvider}.
6008     */
6009    private final boolean checkHoldingPermissionsLocked(
6010            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6011        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6012                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6013
6014        if (pi.applicationInfo.uid == uid) {
6015            return true;
6016        } else if (!pi.exported) {
6017            return false;
6018        }
6019
6020        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6021        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6022        try {
6023            // check if target holds top-level <provider> permissions
6024            if (!readMet && pi.readPermission != null
6025                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6026                readMet = true;
6027            }
6028            if (!writeMet && pi.writePermission != null
6029                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6030                writeMet = true;
6031            }
6032
6033            // track if unprotected read/write is allowed; any denied
6034            // <path-permission> below removes this ability
6035            boolean allowDefaultRead = pi.readPermission == null;
6036            boolean allowDefaultWrite = pi.writePermission == null;
6037
6038            // check if target holds any <path-permission> that match uri
6039            final PathPermission[] pps = pi.pathPermissions;
6040            if (pps != null) {
6041                final String path = grantUri.uri.getPath();
6042                int i = pps.length;
6043                while (i > 0 && (!readMet || !writeMet)) {
6044                    i--;
6045                    PathPermission pp = pps[i];
6046                    if (pp.match(path)) {
6047                        if (!readMet) {
6048                            final String pprperm = pp.getReadPermission();
6049                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6050                                    + pprperm + " for " + pp.getPath()
6051                                    + ": match=" + pp.match(path)
6052                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6053                            if (pprperm != null) {
6054                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6055                                    readMet = true;
6056                                } else {
6057                                    allowDefaultRead = false;
6058                                }
6059                            }
6060                        }
6061                        if (!writeMet) {
6062                            final String ppwperm = pp.getWritePermission();
6063                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6064                                    + ppwperm + " for " + pp.getPath()
6065                                    + ": match=" + pp.match(path)
6066                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6067                            if (ppwperm != null) {
6068                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6069                                    writeMet = true;
6070                                } else {
6071                                    allowDefaultWrite = false;
6072                                }
6073                            }
6074                        }
6075                    }
6076                }
6077            }
6078
6079            // grant unprotected <provider> read/write, if not blocked by
6080            // <path-permission> above
6081            if (allowDefaultRead) readMet = true;
6082            if (allowDefaultWrite) writeMet = true;
6083
6084        } catch (RemoteException e) {
6085            return false;
6086        }
6087
6088        return readMet && writeMet;
6089    }
6090
6091    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6092        ProviderInfo pi = null;
6093        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6094        if (cpr != null) {
6095            pi = cpr.info;
6096        } else {
6097            try {
6098                pi = AppGlobals.getPackageManager().resolveContentProvider(
6099                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6100            } catch (RemoteException ex) {
6101            }
6102        }
6103        return pi;
6104    }
6105
6106    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6107        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6108        if (targetUris != null) {
6109            return targetUris.get(grantUri);
6110        }
6111        return null;
6112    }
6113
6114    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6115            String targetPkg, int targetUid, GrantUri grantUri) {
6116        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6117        if (targetUris == null) {
6118            targetUris = Maps.newArrayMap();
6119            mGrantedUriPermissions.put(targetUid, targetUris);
6120        }
6121
6122        UriPermission perm = targetUris.get(grantUri);
6123        if (perm == null) {
6124            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6125            targetUris.put(grantUri, perm);
6126        }
6127
6128        return perm;
6129    }
6130
6131    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6132            final int modeFlags) {
6133        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6134        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6135                : UriPermission.STRENGTH_OWNED;
6136
6137        // Root gets to do everything.
6138        if (uid == 0) {
6139            return true;
6140        }
6141
6142        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6143        if (perms == null) return false;
6144
6145        // First look for exact match
6146        final UriPermission exactPerm = perms.get(grantUri);
6147        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6148            return true;
6149        }
6150
6151        // No exact match, look for prefixes
6152        final int N = perms.size();
6153        for (int i = 0; i < N; i++) {
6154            final UriPermission perm = perms.valueAt(i);
6155            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6156                    && perm.getStrength(modeFlags) >= minStrength) {
6157                return true;
6158            }
6159        }
6160
6161        return false;
6162    }
6163
6164    @Override
6165    public int checkUriPermission(Uri uri, int pid, int uid,
6166            final int modeFlags, int userId) {
6167        enforceNotIsolatedCaller("checkUriPermission");
6168
6169        // Another redirected-binder-call permissions check as in
6170        // {@link checkComponentPermission}.
6171        Identity tlsIdentity = sCallerIdentity.get();
6172        if (tlsIdentity != null) {
6173            uid = tlsIdentity.uid;
6174            pid = tlsIdentity.pid;
6175        }
6176
6177        // Our own process gets to do everything.
6178        if (pid == MY_PID) {
6179            return PackageManager.PERMISSION_GRANTED;
6180        }
6181        synchronized (this) {
6182            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6183                    ? PackageManager.PERMISSION_GRANTED
6184                    : PackageManager.PERMISSION_DENIED;
6185        }
6186    }
6187
6188    /**
6189     * Check if the targetPkg can be granted permission to access uri by
6190     * the callingUid using the given modeFlags.  Throws a security exception
6191     * if callingUid is not allowed to do this.  Returns the uid of the target
6192     * if the URI permission grant should be performed; returns -1 if it is not
6193     * needed (for example targetPkg already has permission to access the URI).
6194     * If you already know the uid of the target, you can supply it in
6195     * lastTargetUid else set that to -1.
6196     */
6197    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6198            final int modeFlags, int lastTargetUid) {
6199        if (!Intent.isAccessUriMode(modeFlags)) {
6200            return -1;
6201        }
6202
6203        if (targetPkg != null) {
6204            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6205                    "Checking grant " + targetPkg + " permission to " + grantUri);
6206        }
6207
6208        final IPackageManager pm = AppGlobals.getPackageManager();
6209
6210        // If this is not a content: uri, we can't do anything with it.
6211        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6212            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6213                    "Can't grant URI permission for non-content URI: " + grantUri);
6214            return -1;
6215        }
6216
6217        final String authority = grantUri.uri.getAuthority();
6218        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6219        if (pi == null) {
6220            Slog.w(TAG, "No content provider found for permission check: " +
6221                    grantUri.uri.toSafeString());
6222            return -1;
6223        }
6224
6225        int targetUid = lastTargetUid;
6226        if (targetUid < 0 && targetPkg != null) {
6227            try {
6228                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6229                if (targetUid < 0) {
6230                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6231                            "Can't grant URI permission no uid for: " + targetPkg);
6232                    return -1;
6233                }
6234            } catch (RemoteException ex) {
6235                return -1;
6236            }
6237        }
6238
6239        if (targetUid >= 0) {
6240            // First...  does the target actually need this permission?
6241            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6242                // No need to grant the target this permission.
6243                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6244                        "Target " + targetPkg + " already has full permission to " + grantUri);
6245                return -1;
6246            }
6247        } else {
6248            // First...  there is no target package, so can anyone access it?
6249            boolean allowed = pi.exported;
6250            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6251                if (pi.readPermission != null) {
6252                    allowed = false;
6253                }
6254            }
6255            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6256                if (pi.writePermission != null) {
6257                    allowed = false;
6258                }
6259            }
6260            if (allowed) {
6261                return -1;
6262            }
6263        }
6264
6265        // Second...  is the provider allowing granting of URI permissions?
6266        if (!pi.grantUriPermissions) {
6267            throw new SecurityException("Provider " + pi.packageName
6268                    + "/" + pi.name
6269                    + " does not allow granting of Uri permissions (uri "
6270                    + grantUri + ")");
6271        }
6272        if (pi.uriPermissionPatterns != null) {
6273            final int N = pi.uriPermissionPatterns.length;
6274            boolean allowed = false;
6275            for (int i=0; i<N; i++) {
6276                if (pi.uriPermissionPatterns[i] != null
6277                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6278                    allowed = true;
6279                    break;
6280                }
6281            }
6282            if (!allowed) {
6283                throw new SecurityException("Provider " + pi.packageName
6284                        + "/" + pi.name
6285                        + " does not allow granting of permission to path of Uri "
6286                        + grantUri);
6287            }
6288        }
6289
6290        // Third...  does the caller itself have permission to access
6291        // this uri?
6292        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6293            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6294                // Require they hold a strong enough Uri permission
6295                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6296                    throw new SecurityException("Uid " + callingUid
6297                            + " does not have permission to uri " + grantUri);
6298                }
6299            }
6300        }
6301        return targetUid;
6302    }
6303
6304    @Override
6305    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6306            final int modeFlags, int userId) {
6307        enforceNotIsolatedCaller("checkGrantUriPermission");
6308        synchronized(this) {
6309            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6310                    new GrantUri(userId, uri, false), modeFlags, -1);
6311        }
6312    }
6313
6314    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6315            final int modeFlags, UriPermissionOwner owner) {
6316        if (!Intent.isAccessUriMode(modeFlags)) {
6317            return;
6318        }
6319
6320        // So here we are: the caller has the assumed permission
6321        // to the uri, and the target doesn't.  Let's now give this to
6322        // the target.
6323
6324        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6325                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6326
6327        final String authority = grantUri.uri.getAuthority();
6328        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6329        if (pi == null) {
6330            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6331            return;
6332        }
6333
6334        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6335            grantUri.prefix = true;
6336        }
6337        final UriPermission perm = findOrCreateUriPermissionLocked(
6338                pi.packageName, targetPkg, targetUid, grantUri);
6339        perm.grantModes(modeFlags, owner);
6340    }
6341
6342    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6343            final int modeFlags, UriPermissionOwner owner) {
6344        if (targetPkg == null) {
6345            throw new NullPointerException("targetPkg");
6346        }
6347
6348        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6349                -1);
6350        if (targetUid < 0) {
6351            return;
6352        }
6353
6354        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6355                owner);
6356    }
6357
6358    static class NeededUriGrants extends ArrayList<GrantUri> {
6359        final String targetPkg;
6360        final int targetUid;
6361        final int flags;
6362
6363        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6364            this.targetPkg = targetPkg;
6365            this.targetUid = targetUid;
6366            this.flags = flags;
6367        }
6368    }
6369
6370    /**
6371     * Like checkGrantUriPermissionLocked, but takes an Intent.
6372     */
6373    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6374            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6375        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6376                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6377                + " clip=" + (intent != null ? intent.getClipData() : null)
6378                + " from " + intent + "; flags=0x"
6379                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6380
6381        if (targetPkg == null) {
6382            throw new NullPointerException("targetPkg");
6383        }
6384
6385        if (intent == null) {
6386            return null;
6387        }
6388        Uri data = intent.getData();
6389        ClipData clip = intent.getClipData();
6390        if (data == null && clip == null) {
6391            return null;
6392        }
6393
6394        if (data != null) {
6395            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6396            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6397                    needed != null ? needed.targetUid : -1);
6398            if (targetUid > 0) {
6399                if (needed == null) {
6400                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6401                }
6402                needed.add(grantUri);
6403            }
6404        }
6405        if (clip != null) {
6406            for (int i=0; i<clip.getItemCount(); i++) {
6407                Uri uri = clip.getItemAt(i).getUri();
6408                if (uri != null) {
6409                    int targetUid = -1;
6410                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6411                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6412                            needed != null ? needed.targetUid : -1);
6413                    if (targetUid > 0) {
6414                        if (needed == null) {
6415                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6416                        }
6417                        needed.add(grantUri);
6418                    }
6419                } else {
6420                    Intent clipIntent = clip.getItemAt(i).getIntent();
6421                    if (clipIntent != null) {
6422                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6423                                callingUid, targetPkg, clipIntent, mode, needed);
6424                        if (newNeeded != null) {
6425                            needed = newNeeded;
6426                        }
6427                    }
6428                }
6429            }
6430        }
6431
6432        return needed;
6433    }
6434
6435    /**
6436     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6437     */
6438    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6439            UriPermissionOwner owner) {
6440        if (needed != null) {
6441            for (int i=0; i<needed.size(); i++) {
6442                GrantUri grantUri = needed.get(i);
6443                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6444                        grantUri, needed.flags, owner);
6445            }
6446        }
6447    }
6448
6449    void grantUriPermissionFromIntentLocked(int callingUid,
6450            String targetPkg, Intent intent, UriPermissionOwner owner) {
6451        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6452                intent, intent != null ? intent.getFlags() : 0, null);
6453        if (needed == null) {
6454            return;
6455        }
6456
6457        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6458    }
6459
6460    @Override
6461    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6462            final int modeFlags, int userId) {
6463        enforceNotIsolatedCaller("grantUriPermission");
6464        GrantUri grantUri = new GrantUri(userId, uri, false);
6465        synchronized(this) {
6466            final ProcessRecord r = getRecordForAppLocked(caller);
6467            if (r == null) {
6468                throw new SecurityException("Unable to find app for caller "
6469                        + caller
6470                        + " when granting permission to uri " + grantUri);
6471            }
6472            if (targetPkg == null) {
6473                throw new IllegalArgumentException("null target");
6474            }
6475            if (grantUri == null) {
6476                throw new IllegalArgumentException("null uri");
6477            }
6478
6479            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6480                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6481                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6482                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6483
6484            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6485        }
6486    }
6487
6488    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6489        if (perm.modeFlags == 0) {
6490            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6491                    perm.targetUid);
6492            if (perms != null) {
6493                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6494                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6495
6496                perms.remove(perm.uri);
6497                if (perms.isEmpty()) {
6498                    mGrantedUriPermissions.remove(perm.targetUid);
6499                }
6500            }
6501        }
6502    }
6503
6504    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6505        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6506
6507        final IPackageManager pm = AppGlobals.getPackageManager();
6508        final String authority = grantUri.uri.getAuthority();
6509        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6510        if (pi == null) {
6511            Slog.w(TAG, "No content provider found for permission revoke: "
6512                    + grantUri.toSafeString());
6513            return;
6514        }
6515
6516        // Does the caller have this permission on the URI?
6517        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6518            // Right now, if you are not the original owner of the permission,
6519            // you are not allowed to revoke it.
6520            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6521                throw new SecurityException("Uid " + callingUid
6522                        + " does not have permission to uri " + grantUri);
6523            //}
6524        }
6525
6526        boolean persistChanged = false;
6527
6528        // Go through all of the permissions and remove any that match.
6529        int N = mGrantedUriPermissions.size();
6530        for (int i = 0; i < N; i++) {
6531            final int targetUid = mGrantedUriPermissions.keyAt(i);
6532            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6533
6534            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6535                final UriPermission perm = it.next();
6536                if (perm.uri.sourceUserId == grantUri.sourceUserId
6537                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6538                    if (DEBUG_URI_PERMISSION)
6539                        Slog.v(TAG,
6540                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6541                    persistChanged |= perm.revokeModes(
6542                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6543                    if (perm.modeFlags == 0) {
6544                        it.remove();
6545                    }
6546                }
6547            }
6548
6549            if (perms.isEmpty()) {
6550                mGrantedUriPermissions.remove(targetUid);
6551                N--;
6552                i--;
6553            }
6554        }
6555
6556        if (persistChanged) {
6557            schedulePersistUriGrants();
6558        }
6559    }
6560
6561    @Override
6562    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6563            int userId) {
6564        enforceNotIsolatedCaller("revokeUriPermission");
6565        synchronized(this) {
6566            final ProcessRecord r = getRecordForAppLocked(caller);
6567            if (r == null) {
6568                throw new SecurityException("Unable to find app for caller "
6569                        + caller
6570                        + " when revoking permission to uri " + uri);
6571            }
6572            if (uri == null) {
6573                Slog.w(TAG, "revokeUriPermission: null uri");
6574                return;
6575            }
6576
6577            if (!Intent.isAccessUriMode(modeFlags)) {
6578                return;
6579            }
6580
6581            final IPackageManager pm = AppGlobals.getPackageManager();
6582            final String authority = uri.getAuthority();
6583            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6584            if (pi == null) {
6585                Slog.w(TAG, "No content provider found for permission revoke: "
6586                        + uri.toSafeString());
6587                return;
6588            }
6589
6590            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6591        }
6592    }
6593
6594    /**
6595     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6596     * given package.
6597     *
6598     * @param packageName Package name to match, or {@code null} to apply to all
6599     *            packages.
6600     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6601     *            to all users.
6602     * @param persistable If persistable grants should be removed.
6603     */
6604    private void removeUriPermissionsForPackageLocked(
6605            String packageName, int userHandle, boolean persistable) {
6606        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6607            throw new IllegalArgumentException("Must narrow by either package or user");
6608        }
6609
6610        boolean persistChanged = false;
6611
6612        int N = mGrantedUriPermissions.size();
6613        for (int i = 0; i < N; i++) {
6614            final int targetUid = mGrantedUriPermissions.keyAt(i);
6615            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6616
6617            // Only inspect grants matching user
6618            if (userHandle == UserHandle.USER_ALL
6619                    || userHandle == UserHandle.getUserId(targetUid)) {
6620                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6621                    final UriPermission perm = it.next();
6622
6623                    // Only inspect grants matching package
6624                    if (packageName == null || perm.sourcePkg.equals(packageName)
6625                            || perm.targetPkg.equals(packageName)) {
6626                        persistChanged |= perm.revokeModes(
6627                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6628
6629                        // Only remove when no modes remain; any persisted grants
6630                        // will keep this alive.
6631                        if (perm.modeFlags == 0) {
6632                            it.remove();
6633                        }
6634                    }
6635                }
6636
6637                if (perms.isEmpty()) {
6638                    mGrantedUriPermissions.remove(targetUid);
6639                    N--;
6640                    i--;
6641                }
6642            }
6643        }
6644
6645        if (persistChanged) {
6646            schedulePersistUriGrants();
6647        }
6648    }
6649
6650    @Override
6651    public IBinder newUriPermissionOwner(String name) {
6652        enforceNotIsolatedCaller("newUriPermissionOwner");
6653        synchronized(this) {
6654            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6655            return owner.getExternalTokenLocked();
6656        }
6657    }
6658
6659    @Override
6660    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6661            final int modeFlags, int userId) {
6662        synchronized(this) {
6663            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6664            if (owner == null) {
6665                throw new IllegalArgumentException("Unknown owner: " + token);
6666            }
6667            if (fromUid != Binder.getCallingUid()) {
6668                if (Binder.getCallingUid() != Process.myUid()) {
6669                    // Only system code can grant URI permissions on behalf
6670                    // of other users.
6671                    throw new SecurityException("nice try");
6672                }
6673            }
6674            if (targetPkg == null) {
6675                throw new IllegalArgumentException("null target");
6676            }
6677            if (uri == null) {
6678                throw new IllegalArgumentException("null uri");
6679            }
6680
6681            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6682                    modeFlags, owner);
6683        }
6684    }
6685
6686    @Override
6687    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6688        synchronized(this) {
6689            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6690            if (owner == null) {
6691                throw new IllegalArgumentException("Unknown owner: " + token);
6692            }
6693
6694            if (uri == null) {
6695                owner.removeUriPermissionsLocked(mode);
6696            } else {
6697                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6698            }
6699        }
6700    }
6701
6702    private void schedulePersistUriGrants() {
6703        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6704            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6705                    10 * DateUtils.SECOND_IN_MILLIS);
6706        }
6707    }
6708
6709    private void writeGrantedUriPermissions() {
6710        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6711
6712        // Snapshot permissions so we can persist without lock
6713        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6714        synchronized (this) {
6715            final int size = mGrantedUriPermissions.size();
6716            for (int i = 0; i < size; i++) {
6717                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6718                for (UriPermission perm : perms.values()) {
6719                    if (perm.persistedModeFlags != 0) {
6720                        persist.add(perm.snapshot());
6721                    }
6722                }
6723            }
6724        }
6725
6726        FileOutputStream fos = null;
6727        try {
6728            fos = mGrantFile.startWrite();
6729
6730            XmlSerializer out = new FastXmlSerializer();
6731            out.setOutput(fos, "utf-8");
6732            out.startDocument(null, true);
6733            out.startTag(null, TAG_URI_GRANTS);
6734            for (UriPermission.Snapshot perm : persist) {
6735                out.startTag(null, TAG_URI_GRANT);
6736                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6737                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6738                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6739                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6740                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6741                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6742                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6743                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6744                out.endTag(null, TAG_URI_GRANT);
6745            }
6746            out.endTag(null, TAG_URI_GRANTS);
6747            out.endDocument();
6748
6749            mGrantFile.finishWrite(fos);
6750        } catch (IOException e) {
6751            if (fos != null) {
6752                mGrantFile.failWrite(fos);
6753            }
6754        }
6755    }
6756
6757    private void readGrantedUriPermissionsLocked() {
6758        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6759
6760        final long now = System.currentTimeMillis();
6761
6762        FileInputStream fis = null;
6763        try {
6764            fis = mGrantFile.openRead();
6765            final XmlPullParser in = Xml.newPullParser();
6766            in.setInput(fis, null);
6767
6768            int type;
6769            while ((type = in.next()) != END_DOCUMENT) {
6770                final String tag = in.getName();
6771                if (type == START_TAG) {
6772                    if (TAG_URI_GRANT.equals(tag)) {
6773                        final int sourceUserId;
6774                        final int targetUserId;
6775                        final int userHandle = readIntAttribute(in,
6776                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6777                        if (userHandle != UserHandle.USER_NULL) {
6778                            // For backwards compatibility.
6779                            sourceUserId = userHandle;
6780                            targetUserId = userHandle;
6781                        } else {
6782                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6783                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6784                        }
6785                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6786                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6787                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6788                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6789                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6790                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6791
6792                        // Sanity check that provider still belongs to source package
6793                        final ProviderInfo pi = getProviderInfoLocked(
6794                                uri.getAuthority(), sourceUserId);
6795                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6796                            int targetUid = -1;
6797                            try {
6798                                targetUid = AppGlobals.getPackageManager()
6799                                        .getPackageUid(targetPkg, targetUserId);
6800                            } catch (RemoteException e) {
6801                            }
6802                            if (targetUid != -1) {
6803                                final UriPermission perm = findOrCreateUriPermissionLocked(
6804                                        sourcePkg, targetPkg, targetUid,
6805                                        new GrantUri(sourceUserId, uri, prefix));
6806                                perm.initPersistedModes(modeFlags, createdTime);
6807                            }
6808                        } else {
6809                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6810                                    + " but instead found " + pi);
6811                        }
6812                    }
6813                }
6814            }
6815        } catch (FileNotFoundException e) {
6816            // Missing grants is okay
6817        } catch (IOException e) {
6818            Log.wtf(TAG, "Failed reading Uri grants", e);
6819        } catch (XmlPullParserException e) {
6820            Log.wtf(TAG, "Failed reading Uri grants", e);
6821        } finally {
6822            IoUtils.closeQuietly(fis);
6823        }
6824    }
6825
6826    @Override
6827    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6828        enforceNotIsolatedCaller("takePersistableUriPermission");
6829
6830        Preconditions.checkFlagsArgument(modeFlags,
6831                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6832
6833        synchronized (this) {
6834            final int callingUid = Binder.getCallingUid();
6835            boolean persistChanged = false;
6836            GrantUri grantUri = new GrantUri(userId, uri, false);
6837
6838            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6839                    new GrantUri(userId, uri, false));
6840            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6841                    new GrantUri(userId, uri, true));
6842
6843            final boolean exactValid = (exactPerm != null)
6844                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6845            final boolean prefixValid = (prefixPerm != null)
6846                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6847
6848            if (!(exactValid || prefixValid)) {
6849                throw new SecurityException("No persistable permission grants found for UID "
6850                        + callingUid + " and Uri " + grantUri.toSafeString());
6851            }
6852
6853            if (exactValid) {
6854                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6855            }
6856            if (prefixValid) {
6857                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6858            }
6859
6860            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6861
6862            if (persistChanged) {
6863                schedulePersistUriGrants();
6864            }
6865        }
6866    }
6867
6868    @Override
6869    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6870        enforceNotIsolatedCaller("releasePersistableUriPermission");
6871
6872        Preconditions.checkFlagsArgument(modeFlags,
6873                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6874
6875        synchronized (this) {
6876            final int callingUid = Binder.getCallingUid();
6877            boolean persistChanged = false;
6878
6879            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6880                    new GrantUri(userId, uri, false));
6881            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6882                    new GrantUri(userId, uri, true));
6883            if (exactPerm == null && prefixPerm == null) {
6884                throw new SecurityException("No permission grants found for UID " + callingUid
6885                        + " and Uri " + uri.toSafeString());
6886            }
6887
6888            if (exactPerm != null) {
6889                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6890                removeUriPermissionIfNeededLocked(exactPerm);
6891            }
6892            if (prefixPerm != null) {
6893                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6894                removeUriPermissionIfNeededLocked(prefixPerm);
6895            }
6896
6897            if (persistChanged) {
6898                schedulePersistUriGrants();
6899            }
6900        }
6901    }
6902
6903    /**
6904     * Prune any older {@link UriPermission} for the given UID until outstanding
6905     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6906     *
6907     * @return if any mutations occured that require persisting.
6908     */
6909    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6910        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6911        if (perms == null) return false;
6912        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6913
6914        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6915        for (UriPermission perm : perms.values()) {
6916            if (perm.persistedModeFlags != 0) {
6917                persisted.add(perm);
6918            }
6919        }
6920
6921        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6922        if (trimCount <= 0) return false;
6923
6924        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6925        for (int i = 0; i < trimCount; i++) {
6926            final UriPermission perm = persisted.get(i);
6927
6928            if (DEBUG_URI_PERMISSION) {
6929                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6930            }
6931
6932            perm.releasePersistableModes(~0);
6933            removeUriPermissionIfNeededLocked(perm);
6934        }
6935
6936        return true;
6937    }
6938
6939    @Override
6940    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6941            String packageName, boolean incoming) {
6942        enforceNotIsolatedCaller("getPersistedUriPermissions");
6943        Preconditions.checkNotNull(packageName, "packageName");
6944
6945        final int callingUid = Binder.getCallingUid();
6946        final IPackageManager pm = AppGlobals.getPackageManager();
6947        try {
6948            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6949            if (packageUid != callingUid) {
6950                throw new SecurityException(
6951                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6952            }
6953        } catch (RemoteException e) {
6954            throw new SecurityException("Failed to verify package name ownership");
6955        }
6956
6957        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6958        synchronized (this) {
6959            if (incoming) {
6960                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6961                        callingUid);
6962                if (perms == null) {
6963                    Slog.w(TAG, "No permission grants found for " + packageName);
6964                } else {
6965                    for (UriPermission perm : perms.values()) {
6966                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6967                            result.add(perm.buildPersistedPublicApiObject());
6968                        }
6969                    }
6970                }
6971            } else {
6972                final int size = mGrantedUriPermissions.size();
6973                for (int i = 0; i < size; i++) {
6974                    final ArrayMap<GrantUri, UriPermission> perms =
6975                            mGrantedUriPermissions.valueAt(i);
6976                    for (UriPermission perm : perms.values()) {
6977                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6978                            result.add(perm.buildPersistedPublicApiObject());
6979                        }
6980                    }
6981                }
6982            }
6983        }
6984        return new ParceledListSlice<android.content.UriPermission>(result);
6985    }
6986
6987    @Override
6988    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6989        synchronized (this) {
6990            ProcessRecord app =
6991                who != null ? getRecordForAppLocked(who) : null;
6992            if (app == null) return;
6993
6994            Message msg = Message.obtain();
6995            msg.what = WAIT_FOR_DEBUGGER_MSG;
6996            msg.obj = app;
6997            msg.arg1 = waiting ? 1 : 0;
6998            mHandler.sendMessage(msg);
6999        }
7000    }
7001
7002    @Override
7003    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7004        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7005        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7006        outInfo.availMem = Process.getFreeMemory();
7007        outInfo.totalMem = Process.getTotalMemory();
7008        outInfo.threshold = homeAppMem;
7009        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7010        outInfo.hiddenAppThreshold = cachedAppMem;
7011        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7012                ProcessList.SERVICE_ADJ);
7013        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7014                ProcessList.VISIBLE_APP_ADJ);
7015        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7016                ProcessList.FOREGROUND_APP_ADJ);
7017    }
7018
7019    // =========================================================
7020    // TASK MANAGEMENT
7021    // =========================================================
7022
7023    @Override
7024    public List<IAppTask> getAppTasks() {
7025        int callingUid = Binder.getCallingUid();
7026        long ident = Binder.clearCallingIdentity();
7027        synchronized(this) {
7028            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7029            try {
7030                if (localLOGV) Slog.v(TAG, "getAppTasks");
7031
7032                final int N = mRecentTasks.size();
7033                for (int i = 0; i < N; i++) {
7034                    TaskRecord tr = mRecentTasks.get(i);
7035                    // Skip tasks that are not created by the caller
7036                    if (tr.creatorUid == callingUid) {
7037                        ActivityManager.RecentTaskInfo taskInfo =
7038                                createRecentTaskInfoFromTaskRecord(tr);
7039                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7040                        list.add(taskImpl);
7041                    }
7042                }
7043            } finally {
7044                Binder.restoreCallingIdentity(ident);
7045            }
7046            return list;
7047        }
7048    }
7049
7050    @Override
7051    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7052        final int callingUid = Binder.getCallingUid();
7053        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7054
7055        synchronized(this) {
7056            if (localLOGV) Slog.v(
7057                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7058
7059            final boolean allowed = checkCallingPermission(
7060                    android.Manifest.permission.GET_TASKS)
7061                    == PackageManager.PERMISSION_GRANTED;
7062            if (!allowed) {
7063                Slog.w(TAG, "getTasks: caller " + callingUid
7064                        + " does not hold GET_TASKS; limiting output");
7065            }
7066
7067            // TODO: Improve with MRU list from all ActivityStacks.
7068            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7069        }
7070
7071        return list;
7072    }
7073
7074    TaskRecord getMostRecentTask() {
7075        return mRecentTasks.get(0);
7076    }
7077
7078    /**
7079     * Creates a new RecentTaskInfo from a TaskRecord.
7080     */
7081    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7082        // Update the task description to reflect any changes in the task stack
7083        tr.updateTaskDescription();
7084
7085        // Compose the recent task info
7086        ActivityManager.RecentTaskInfo rti
7087                = new ActivityManager.RecentTaskInfo();
7088        rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7089        rti.persistentId = tr.taskId;
7090        rti.baseIntent = new Intent(tr.getBaseIntent());
7091        rti.origActivity = tr.origActivity;
7092        rti.description = tr.lastDescription;
7093        rti.stackId = tr.stack.mStackId;
7094        rti.userId = tr.userId;
7095        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7096        return rti;
7097    }
7098
7099    @Override
7100    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7101            int flags, int userId) {
7102        final int callingUid = Binder.getCallingUid();
7103        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7104                false, true, "getRecentTasks", null);
7105
7106        synchronized (this) {
7107            final boolean allowed = checkCallingPermission(
7108                    android.Manifest.permission.GET_TASKS)
7109                    == PackageManager.PERMISSION_GRANTED;
7110            if (!allowed) {
7111                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7112                        + " does not hold GET_TASKS; limiting output");
7113            }
7114            final boolean detailed = checkCallingPermission(
7115                    android.Manifest.permission.GET_DETAILED_TASKS)
7116                    == PackageManager.PERMISSION_GRANTED;
7117
7118            IPackageManager pm = AppGlobals.getPackageManager();
7119
7120            final int N = mRecentTasks.size();
7121            ArrayList<ActivityManager.RecentTaskInfo> res
7122                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7123                            maxNum < N ? maxNum : N);
7124
7125            final Set<Integer> includedUsers;
7126            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7127                includedUsers = getProfileIdsLocked(userId);
7128            } else {
7129                includedUsers = new HashSet<Integer>();
7130            }
7131            includedUsers.add(Integer.valueOf(userId));
7132            for (int i=0; i<N && maxNum > 0; i++) {
7133                TaskRecord tr = mRecentTasks.get(i);
7134                // Only add calling user or related users recent tasks
7135                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7136
7137                // Return the entry if desired by the caller.  We always return
7138                // the first entry, because callers always expect this to be the
7139                // foreground app.  We may filter others if the caller has
7140                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7141                // we should exclude the entry.
7142
7143                if (i == 0
7144                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7145                        || (tr.intent == null)
7146                        || ((tr.intent.getFlags()
7147                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7148                    if (!allowed) {
7149                        // If the caller doesn't have the GET_TASKS permission, then only
7150                        // allow them to see a small subset of tasks -- their own and home.
7151                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7152                            continue;
7153                        }
7154                    }
7155
7156                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7157                    if (!detailed) {
7158                        rti.baseIntent.replaceExtras((Bundle)null);
7159                    }
7160
7161                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7162                        // Check whether this activity is currently available.
7163                        try {
7164                            if (rti.origActivity != null) {
7165                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7166                                        == null) {
7167                                    continue;
7168                                }
7169                            } else if (rti.baseIntent != null) {
7170                                if (pm.queryIntentActivities(rti.baseIntent,
7171                                        null, 0, userId) == null) {
7172                                    continue;
7173                                }
7174                            }
7175                        } catch (RemoteException e) {
7176                            // Will never happen.
7177                        }
7178                    }
7179
7180                    res.add(rti);
7181                    maxNum--;
7182                }
7183            }
7184            return res;
7185        }
7186    }
7187
7188    private TaskRecord recentTaskForIdLocked(int id) {
7189        final int N = mRecentTasks.size();
7190            for (int i=0; i<N; i++) {
7191                TaskRecord tr = mRecentTasks.get(i);
7192                if (tr.taskId == id) {
7193                    return tr;
7194                }
7195            }
7196            return null;
7197    }
7198
7199    @Override
7200    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7201        synchronized (this) {
7202            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7203                    "getTaskThumbnails()");
7204            TaskRecord tr = recentTaskForIdLocked(id);
7205            if (tr != null) {
7206                return tr.getTaskThumbnailsLocked();
7207            }
7208        }
7209        return null;
7210    }
7211
7212    @Override
7213    public Bitmap getTaskTopThumbnail(int id) {
7214        synchronized (this) {
7215            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7216                    "getTaskTopThumbnail()");
7217            TaskRecord tr = recentTaskForIdLocked(id);
7218            if (tr != null) {
7219                return tr.getTaskTopThumbnailLocked();
7220            }
7221        }
7222        return null;
7223    }
7224
7225    @Override
7226    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7227        synchronized (this) {
7228            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7229            if (r != null) {
7230                r.taskDescription = td;
7231                r.task.updateTaskDescription();
7232            }
7233        }
7234    }
7235
7236    @Override
7237    public boolean removeSubTask(int taskId, int subTaskIndex) {
7238        synchronized (this) {
7239            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7240                    "removeSubTask()");
7241            long ident = Binder.clearCallingIdentity();
7242            try {
7243                TaskRecord tr = recentTaskForIdLocked(taskId);
7244                if (tr != null) {
7245                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7246                }
7247                return false;
7248            } finally {
7249                Binder.restoreCallingIdentity(ident);
7250            }
7251        }
7252    }
7253
7254    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7255        if (!pr.killedByAm) {
7256            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7257            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7258                    pr.processName, pr.setAdj, reason);
7259            pr.killedByAm = true;
7260            Process.killProcessQuiet(pr.pid);
7261        }
7262    }
7263
7264    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7265        tr.disposeThumbnail();
7266        mRecentTasks.remove(tr);
7267        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7268        Intent baseIntent = new Intent(
7269                tr.intent != null ? tr.intent : tr.affinityIntent);
7270        ComponentName component = baseIntent.getComponent();
7271        if (component == null) {
7272            Slog.w(TAG, "Now component for base intent of task: " + tr);
7273            return;
7274        }
7275
7276        // Find any running services associated with this app.
7277        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7278
7279        if (killProcesses) {
7280            // Find any running processes associated with this app.
7281            final String pkg = component.getPackageName();
7282            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7283            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7284            for (int i=0; i<pmap.size(); i++) {
7285                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7286                for (int j=0; j<uids.size(); j++) {
7287                    ProcessRecord proc = uids.valueAt(j);
7288                    if (proc.userId != tr.userId) {
7289                        continue;
7290                    }
7291                    if (!proc.pkgList.containsKey(pkg)) {
7292                        continue;
7293                    }
7294                    procs.add(proc);
7295                }
7296            }
7297
7298            // Kill the running processes.
7299            for (int i=0; i<procs.size(); i++) {
7300                ProcessRecord pr = procs.get(i);
7301                if (pr == mHomeProcess) {
7302                    // Don't kill the home process along with tasks from the same package.
7303                    continue;
7304                }
7305                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7306                    killUnneededProcessLocked(pr, "remove task");
7307                } else {
7308                    pr.waitingToKill = "remove task";
7309                }
7310            }
7311        }
7312    }
7313
7314    /**
7315     * Removes the task with the specified task id.
7316     *
7317     * @param taskId Identifier of the task to be removed.
7318     * @param flags Additional operational flags.  May be 0 or
7319     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7320     * @return Returns true if the given task was found and removed.
7321     */
7322    private boolean removeTaskByIdLocked(int taskId, int flags) {
7323        TaskRecord tr = recentTaskForIdLocked(taskId);
7324        if (tr != null) {
7325            tr.removeTaskActivitiesLocked(-1, false);
7326            cleanUpRemovedTaskLocked(tr, flags);
7327            return true;
7328        }
7329        return false;
7330    }
7331
7332    @Override
7333    public boolean removeTask(int taskId, int flags) {
7334        synchronized (this) {
7335            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7336                    "removeTask()");
7337            long ident = Binder.clearCallingIdentity();
7338            try {
7339                return removeTaskByIdLocked(taskId, flags);
7340            } finally {
7341                Binder.restoreCallingIdentity(ident);
7342            }
7343        }
7344    }
7345
7346    /**
7347     * TODO: Add mController hook
7348     */
7349    @Override
7350    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7351        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7352                "moveTaskToFront()");
7353
7354        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7355        synchronized(this) {
7356            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7357                    Binder.getCallingUid(), "Task to front")) {
7358                ActivityOptions.abort(options);
7359                return;
7360            }
7361            final long origId = Binder.clearCallingIdentity();
7362            try {
7363                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7364                if (task == null) {
7365                    return;
7366                }
7367                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7368                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7369                    return;
7370                }
7371                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7372            } finally {
7373                Binder.restoreCallingIdentity(origId);
7374            }
7375            ActivityOptions.abort(options);
7376        }
7377    }
7378
7379    @Override
7380    public void moveTaskToBack(int taskId) {
7381        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7382                "moveTaskToBack()");
7383
7384        synchronized(this) {
7385            TaskRecord tr = recentTaskForIdLocked(taskId);
7386            if (tr != null) {
7387                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7388                ActivityStack stack = tr.stack;
7389                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7390                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7391                            Binder.getCallingUid(), "Task to back")) {
7392                        return;
7393                    }
7394                }
7395                final long origId = Binder.clearCallingIdentity();
7396                try {
7397                    stack.moveTaskToBackLocked(taskId, null);
7398                } finally {
7399                    Binder.restoreCallingIdentity(origId);
7400                }
7401            }
7402        }
7403    }
7404
7405    /**
7406     * Moves an activity, and all of the other activities within the same task, to the bottom
7407     * of the history stack.  The activity's order within the task is unchanged.
7408     *
7409     * @param token A reference to the activity we wish to move
7410     * @param nonRoot If false then this only works if the activity is the root
7411     *                of a task; if true it will work for any activity in a task.
7412     * @return Returns true if the move completed, false if not.
7413     */
7414    @Override
7415    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7416        enforceNotIsolatedCaller("moveActivityTaskToBack");
7417        synchronized(this) {
7418            final long origId = Binder.clearCallingIdentity();
7419            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7420            if (taskId >= 0) {
7421                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7422            }
7423            Binder.restoreCallingIdentity(origId);
7424        }
7425        return false;
7426    }
7427
7428    @Override
7429    public void moveTaskBackwards(int task) {
7430        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7431                "moveTaskBackwards()");
7432
7433        synchronized(this) {
7434            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7435                    Binder.getCallingUid(), "Task backwards")) {
7436                return;
7437            }
7438            final long origId = Binder.clearCallingIdentity();
7439            moveTaskBackwardsLocked(task);
7440            Binder.restoreCallingIdentity(origId);
7441        }
7442    }
7443
7444    private final void moveTaskBackwardsLocked(int task) {
7445        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7446    }
7447
7448    @Override
7449    public IBinder getHomeActivityToken() throws RemoteException {
7450        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7451                "getHomeActivityToken()");
7452        synchronized (this) {
7453            return mStackSupervisor.getHomeActivityToken();
7454        }
7455    }
7456
7457    @Override
7458    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7459            IActivityContainerCallback callback) throws RemoteException {
7460        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7461                "createActivityContainer()");
7462        synchronized (this) {
7463            if (parentActivityToken == null) {
7464                throw new IllegalArgumentException("parent token must not be null");
7465            }
7466            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7467            if (r == null) {
7468                return null;
7469            }
7470            if (callback == null) {
7471                throw new IllegalArgumentException("callback must not be null");
7472            }
7473            return mStackSupervisor.createActivityContainer(r, callback);
7474        }
7475    }
7476
7477    @Override
7478    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7479        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7480                "deleteActivityContainer()");
7481        synchronized (this) {
7482            mStackSupervisor.deleteActivityContainer(container);
7483        }
7484    }
7485
7486    @Override
7487    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7488            throws RemoteException {
7489        synchronized (this) {
7490            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7491            if (stack != null) {
7492                return stack.mActivityContainer;
7493            }
7494            return null;
7495        }
7496    }
7497
7498    @Override
7499    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7500        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7501                "moveTaskToStack()");
7502        if (stackId == HOME_STACK_ID) {
7503            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7504                    new RuntimeException("here").fillInStackTrace());
7505        }
7506        synchronized (this) {
7507            long ident = Binder.clearCallingIdentity();
7508            try {
7509                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7510                        + stackId + " toTop=" + toTop);
7511                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7512            } finally {
7513                Binder.restoreCallingIdentity(ident);
7514            }
7515        }
7516    }
7517
7518    @Override
7519    public void resizeStack(int stackBoxId, Rect bounds) {
7520        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7521                "resizeStackBox()");
7522        long ident = Binder.clearCallingIdentity();
7523        try {
7524            mWindowManager.resizeStack(stackBoxId, bounds);
7525        } finally {
7526            Binder.restoreCallingIdentity(ident);
7527        }
7528    }
7529
7530    @Override
7531    public List<StackInfo> getAllStackInfos() {
7532        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7533                "getAllStackInfos()");
7534        long ident = Binder.clearCallingIdentity();
7535        try {
7536            synchronized (this) {
7537                return mStackSupervisor.getAllStackInfosLocked();
7538            }
7539        } finally {
7540            Binder.restoreCallingIdentity(ident);
7541        }
7542    }
7543
7544    @Override
7545    public StackInfo getStackInfo(int stackId) {
7546        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7547                "getStackInfo()");
7548        long ident = Binder.clearCallingIdentity();
7549        try {
7550            synchronized (this) {
7551                return mStackSupervisor.getStackInfoLocked(stackId);
7552            }
7553        } finally {
7554            Binder.restoreCallingIdentity(ident);
7555        }
7556    }
7557
7558    @Override
7559    public boolean isInHomeStack(int taskId) {
7560        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7561                "getStackInfo()");
7562        long ident = Binder.clearCallingIdentity();
7563        try {
7564            synchronized (this) {
7565                TaskRecord tr = recentTaskForIdLocked(taskId);
7566                if (tr != null) {
7567                    return tr.stack.isHomeStack();
7568                }
7569            }
7570        } finally {
7571            Binder.restoreCallingIdentity(ident);
7572        }
7573        return false;
7574    }
7575
7576    @Override
7577    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7578        synchronized(this) {
7579            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7580        }
7581    }
7582
7583    private boolean isLockTaskAuthorized(ComponentName name) {
7584        final DevicePolicyManager dpm = (DevicePolicyManager)
7585                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7586        return dpm != null && dpm.isLockTaskPermitted(name);
7587    }
7588
7589    private void startLockTaskMode(TaskRecord task) {
7590        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7591            return;
7592        }
7593        long ident = Binder.clearCallingIdentity();
7594        try {
7595            synchronized (this) {
7596                // Since we lost lock on task, make sure it is still there.
7597                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7598                if (task != null) {
7599                    mStackSupervisor.setLockTaskModeLocked(task);
7600                }
7601            }
7602        } finally {
7603            Binder.restoreCallingIdentity(ident);
7604        }
7605    }
7606
7607    @Override
7608    public void startLockTaskMode(int taskId) {
7609        long ident = Binder.clearCallingIdentity();
7610        try {
7611            final TaskRecord task;
7612            synchronized (this) {
7613                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7614            }
7615            if (task != null) {
7616                startLockTaskMode(task);
7617            }
7618        } finally {
7619            Binder.restoreCallingIdentity(ident);
7620        }
7621    }
7622
7623    @Override
7624    public void startLockTaskMode(IBinder token) {
7625        long ident = Binder.clearCallingIdentity();
7626        try {
7627            final TaskRecord task;
7628            synchronized (this) {
7629                final ActivityRecord r = ActivityRecord.forToken(token);
7630                if (r == null) {
7631                    return;
7632                }
7633                task = r.task;
7634            }
7635            if (task != null) {
7636                startLockTaskMode(task);
7637            }
7638        } finally {
7639            Binder.restoreCallingIdentity(ident);
7640        }
7641    }
7642
7643    @Override
7644    public void stopLockTaskMode() {
7645        // Check if the calling task is eligible to use lock task
7646        final int uid = Binder.getCallingUid();
7647        try {
7648            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7649            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7650                return;
7651            }
7652        } catch (RemoteException e) {
7653            Log.d(TAG, "stopLockTaskMode " + e);
7654            return;
7655        }
7656        // Stop lock task
7657        synchronized (this) {
7658            mStackSupervisor.setLockTaskModeLocked(null);
7659        }
7660    }
7661
7662    @Override
7663    public boolean isInLockTaskMode() {
7664        synchronized (this) {
7665            return mStackSupervisor.isInLockTaskMode();
7666        }
7667    }
7668
7669    // =========================================================
7670    // CONTENT PROVIDERS
7671    // =========================================================
7672
7673    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7674        List<ProviderInfo> providers = null;
7675        try {
7676            providers = AppGlobals.getPackageManager().
7677                queryContentProviders(app.processName, app.uid,
7678                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7679        } catch (RemoteException ex) {
7680        }
7681        if (DEBUG_MU)
7682            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7683        int userId = app.userId;
7684        if (providers != null) {
7685            int N = providers.size();
7686            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7687            for (int i=0; i<N; i++) {
7688                ProviderInfo cpi =
7689                    (ProviderInfo)providers.get(i);
7690                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7691                        cpi.name, cpi.flags);
7692                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7693                    // This is a singleton provider, but a user besides the
7694                    // default user is asking to initialize a process it runs
7695                    // in...  well, no, it doesn't actually run in this process,
7696                    // it runs in the process of the default user.  Get rid of it.
7697                    providers.remove(i);
7698                    N--;
7699                    i--;
7700                    continue;
7701                }
7702
7703                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7704                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7705                if (cpr == null) {
7706                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7707                    mProviderMap.putProviderByClass(comp, cpr);
7708                }
7709                if (DEBUG_MU)
7710                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7711                app.pubProviders.put(cpi.name, cpr);
7712                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7713                    // Don't add this if it is a platform component that is marked
7714                    // to run in multiple processes, because this is actually
7715                    // part of the framework so doesn't make sense to track as a
7716                    // separate apk in the process.
7717                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7718                }
7719                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7720            }
7721        }
7722        return providers;
7723    }
7724
7725    /**
7726     * Check if {@link ProcessRecord} has a possible chance at accessing the
7727     * given {@link ProviderInfo}. Final permission checking is always done
7728     * in {@link ContentProvider}.
7729     */
7730    private final String checkContentProviderPermissionLocked(
7731            ProviderInfo cpi, ProcessRecord r, int userId) {
7732        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7733        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7734        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7735        // Looking for cross-user grants before to enforce the typical cross-users permissions
7736        if (userId != UserHandle.getUserId(callingUid)) {
7737            if (perms != null) {
7738                for (GrantUri grantUri : perms.keySet()) {
7739                    if (grantUri.sourceUserId == userId) {
7740                        String authority = grantUri.uri.getAuthority();
7741                        if (authority.equals(cpi.authority)) {
7742                            return null;
7743                        }
7744                    }
7745                }
7746            }
7747        }
7748        userId = handleIncomingUser(callingPid, callingUid, userId,
7749                false, true, "checkContentProviderPermissionLocked", null);
7750        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7751                cpi.applicationInfo.uid, cpi.exported)
7752                == PackageManager.PERMISSION_GRANTED) {
7753            return null;
7754        }
7755        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7756                cpi.applicationInfo.uid, cpi.exported)
7757                == PackageManager.PERMISSION_GRANTED) {
7758            return null;
7759        }
7760
7761        PathPermission[] pps = cpi.pathPermissions;
7762        if (pps != null) {
7763            int i = pps.length;
7764            while (i > 0) {
7765                i--;
7766                PathPermission pp = pps[i];
7767                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7768                        cpi.applicationInfo.uid, cpi.exported)
7769                        == PackageManager.PERMISSION_GRANTED) {
7770                    return null;
7771                }
7772                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7773                        cpi.applicationInfo.uid, cpi.exported)
7774                        == PackageManager.PERMISSION_GRANTED) {
7775                    return null;
7776                }
7777            }
7778        }
7779
7780        if (perms != null) {
7781            for (GrantUri grantUri : perms.keySet()) {
7782                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7783                    return null;
7784                }
7785            }
7786        }
7787
7788        String msg;
7789        if (!cpi.exported) {
7790            msg = "Permission Denial: opening provider " + cpi.name
7791                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7792                    + ", uid=" + callingUid + ") that is not exported from uid "
7793                    + cpi.applicationInfo.uid;
7794        } else {
7795            msg = "Permission Denial: opening provider " + cpi.name
7796                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7797                    + ", uid=" + callingUid + ") requires "
7798                    + cpi.readPermission + " or " + cpi.writePermission;
7799        }
7800        Slog.w(TAG, msg);
7801        return msg;
7802    }
7803
7804    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7805            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7806        if (r != null) {
7807            for (int i=0; i<r.conProviders.size(); i++) {
7808                ContentProviderConnection conn = r.conProviders.get(i);
7809                if (conn.provider == cpr) {
7810                    if (DEBUG_PROVIDER) Slog.v(TAG,
7811                            "Adding provider requested by "
7812                            + r.processName + " from process "
7813                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7814                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7815                    if (stable) {
7816                        conn.stableCount++;
7817                        conn.numStableIncs++;
7818                    } else {
7819                        conn.unstableCount++;
7820                        conn.numUnstableIncs++;
7821                    }
7822                    return conn;
7823                }
7824            }
7825            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7826            if (stable) {
7827                conn.stableCount = 1;
7828                conn.numStableIncs = 1;
7829            } else {
7830                conn.unstableCount = 1;
7831                conn.numUnstableIncs = 1;
7832            }
7833            cpr.connections.add(conn);
7834            r.conProviders.add(conn);
7835            return conn;
7836        }
7837        cpr.addExternalProcessHandleLocked(externalProcessToken);
7838        return null;
7839    }
7840
7841    boolean decProviderCountLocked(ContentProviderConnection conn,
7842            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7843        if (conn != null) {
7844            cpr = conn.provider;
7845            if (DEBUG_PROVIDER) Slog.v(TAG,
7846                    "Removing provider requested by "
7847                    + conn.client.processName + " from process "
7848                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7849                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7850            if (stable) {
7851                conn.stableCount--;
7852            } else {
7853                conn.unstableCount--;
7854            }
7855            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7856                cpr.connections.remove(conn);
7857                conn.client.conProviders.remove(conn);
7858                return true;
7859            }
7860            return false;
7861        }
7862        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7863        return false;
7864    }
7865
7866    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7867            String name, IBinder token, boolean stable, int userId) {
7868        ContentProviderRecord cpr;
7869        ContentProviderConnection conn = null;
7870        ProviderInfo cpi = null;
7871
7872        synchronized(this) {
7873            ProcessRecord r = null;
7874            if (caller != null) {
7875                r = getRecordForAppLocked(caller);
7876                if (r == null) {
7877                    throw new SecurityException(
7878                            "Unable to find app for caller " + caller
7879                          + " (pid=" + Binder.getCallingPid()
7880                          + ") when getting content provider " + name);
7881                }
7882            }
7883
7884            // First check if this content provider has been published...
7885            cpr = mProviderMap.getProviderByName(name, userId);
7886            boolean providerRunning = cpr != null;
7887            if (providerRunning) {
7888                cpi = cpr.info;
7889                String msg;
7890                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7891                    throw new SecurityException(msg);
7892                }
7893
7894                if (r != null && cpr.canRunHere(r)) {
7895                    // This provider has been published or is in the process
7896                    // of being published...  but it is also allowed to run
7897                    // in the caller's process, so don't make a connection
7898                    // and just let the caller instantiate its own instance.
7899                    ContentProviderHolder holder = cpr.newHolder(null);
7900                    // don't give caller the provider object, it needs
7901                    // to make its own.
7902                    holder.provider = null;
7903                    return holder;
7904                }
7905
7906                final long origId = Binder.clearCallingIdentity();
7907
7908                // In this case the provider instance already exists, so we can
7909                // return it right away.
7910                conn = incProviderCountLocked(r, cpr, token, stable);
7911                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7912                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7913                        // If this is a perceptible app accessing the provider,
7914                        // make sure to count it as being accessed and thus
7915                        // back up on the LRU list.  This is good because
7916                        // content providers are often expensive to start.
7917                        updateLruProcessLocked(cpr.proc, false, null);
7918                    }
7919                }
7920
7921                if (cpr.proc != null) {
7922                    if (false) {
7923                        if (cpr.name.flattenToShortString().equals(
7924                                "com.android.providers.calendar/.CalendarProvider2")) {
7925                            Slog.v(TAG, "****************** KILLING "
7926                                + cpr.name.flattenToShortString());
7927                            Process.killProcess(cpr.proc.pid);
7928                        }
7929                    }
7930                    boolean success = updateOomAdjLocked(cpr.proc);
7931                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7932                    // NOTE: there is still a race here where a signal could be
7933                    // pending on the process even though we managed to update its
7934                    // adj level.  Not sure what to do about this, but at least
7935                    // the race is now smaller.
7936                    if (!success) {
7937                        // Uh oh...  it looks like the provider's process
7938                        // has been killed on us.  We need to wait for a new
7939                        // process to be started, and make sure its death
7940                        // doesn't kill our process.
7941                        Slog.i(TAG,
7942                                "Existing provider " + cpr.name.flattenToShortString()
7943                                + " is crashing; detaching " + r);
7944                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7945                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7946                        if (!lastRef) {
7947                            // This wasn't the last ref our process had on
7948                            // the provider...  we have now been killed, bail.
7949                            return null;
7950                        }
7951                        providerRunning = false;
7952                        conn = null;
7953                    }
7954                }
7955
7956                Binder.restoreCallingIdentity(origId);
7957            }
7958
7959            boolean singleton;
7960            if (!providerRunning) {
7961                try {
7962                    cpi = AppGlobals.getPackageManager().
7963                        resolveContentProvider(name,
7964                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7965                } catch (RemoteException ex) {
7966                }
7967                if (cpi == null) {
7968                    return null;
7969                }
7970                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7971                        cpi.name, cpi.flags);
7972                if (singleton) {
7973                    userId = 0;
7974                }
7975                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7976
7977                String msg;
7978                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7979                    throw new SecurityException(msg);
7980                }
7981
7982                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7983                        && !cpi.processName.equals("system")) {
7984                    // If this content provider does not run in the system
7985                    // process, and the system is not yet ready to run other
7986                    // processes, then fail fast instead of hanging.
7987                    throw new IllegalArgumentException(
7988                            "Attempt to launch content provider before system ready");
7989                }
7990
7991                // Make sure that the user who owns this provider is started.  If not,
7992                // we don't want to allow it to run.
7993                if (mStartedUsers.get(userId) == null) {
7994                    Slog.w(TAG, "Unable to launch app "
7995                            + cpi.applicationInfo.packageName + "/"
7996                            + cpi.applicationInfo.uid + " for provider "
7997                            + name + ": user " + userId + " is stopped");
7998                    return null;
7999                }
8000
8001                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8002                cpr = mProviderMap.getProviderByClass(comp, userId);
8003                final boolean firstClass = cpr == null;
8004                if (firstClass) {
8005                    try {
8006                        ApplicationInfo ai =
8007                            AppGlobals.getPackageManager().
8008                                getApplicationInfo(
8009                                        cpi.applicationInfo.packageName,
8010                                        STOCK_PM_FLAGS, userId);
8011                        if (ai == null) {
8012                            Slog.w(TAG, "No package info for content provider "
8013                                    + cpi.name);
8014                            return null;
8015                        }
8016                        ai = getAppInfoForUser(ai, userId);
8017                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8018                    } catch (RemoteException ex) {
8019                        // pm is in same process, this will never happen.
8020                    }
8021                }
8022
8023                if (r != null && cpr.canRunHere(r)) {
8024                    // If this is a multiprocess provider, then just return its
8025                    // info and allow the caller to instantiate it.  Only do
8026                    // this if the provider is the same user as the caller's
8027                    // process, or can run as root (so can be in any process).
8028                    return cpr.newHolder(null);
8029                }
8030
8031                if (DEBUG_PROVIDER) {
8032                    RuntimeException e = new RuntimeException("here");
8033                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8034                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8035                }
8036
8037                // This is single process, and our app is now connecting to it.
8038                // See if we are already in the process of launching this
8039                // provider.
8040                final int N = mLaunchingProviders.size();
8041                int i;
8042                for (i=0; i<N; i++) {
8043                    if (mLaunchingProviders.get(i) == cpr) {
8044                        break;
8045                    }
8046                }
8047
8048                // If the provider is not already being launched, then get it
8049                // started.
8050                if (i >= N) {
8051                    final long origId = Binder.clearCallingIdentity();
8052
8053                    try {
8054                        // Content provider is now in use, its package can't be stopped.
8055                        try {
8056                            AppGlobals.getPackageManager().setPackageStoppedState(
8057                                    cpr.appInfo.packageName, false, userId);
8058                        } catch (RemoteException e) {
8059                        } catch (IllegalArgumentException e) {
8060                            Slog.w(TAG, "Failed trying to unstop package "
8061                                    + cpr.appInfo.packageName + ": " + e);
8062                        }
8063
8064                        // Use existing process if already started
8065                        ProcessRecord proc = getProcessRecordLocked(
8066                                cpi.processName, cpr.appInfo.uid, false);
8067                        if (proc != null && proc.thread != null) {
8068                            if (DEBUG_PROVIDER) {
8069                                Slog.d(TAG, "Installing in existing process " + proc);
8070                            }
8071                            proc.pubProviders.put(cpi.name, cpr);
8072                            try {
8073                                proc.thread.scheduleInstallProvider(cpi);
8074                            } catch (RemoteException e) {
8075                            }
8076                        } else {
8077                            proc = startProcessLocked(cpi.processName,
8078                                    cpr.appInfo, false, 0, "content provider",
8079                                    new ComponentName(cpi.applicationInfo.packageName,
8080                                            cpi.name), false, false, false);
8081                            if (proc == null) {
8082                                Slog.w(TAG, "Unable to launch app "
8083                                        + cpi.applicationInfo.packageName + "/"
8084                                        + cpi.applicationInfo.uid + " for provider "
8085                                        + name + ": process is bad");
8086                                return null;
8087                            }
8088                        }
8089                        cpr.launchingApp = proc;
8090                        mLaunchingProviders.add(cpr);
8091                    } finally {
8092                        Binder.restoreCallingIdentity(origId);
8093                    }
8094                }
8095
8096                // Make sure the provider is published (the same provider class
8097                // may be published under multiple names).
8098                if (firstClass) {
8099                    mProviderMap.putProviderByClass(comp, cpr);
8100                }
8101
8102                mProviderMap.putProviderByName(name, cpr);
8103                conn = incProviderCountLocked(r, cpr, token, stable);
8104                if (conn != null) {
8105                    conn.waiting = true;
8106                }
8107            }
8108        }
8109
8110        // Wait for the provider to be published...
8111        synchronized (cpr) {
8112            while (cpr.provider == null) {
8113                if (cpr.launchingApp == null) {
8114                    Slog.w(TAG, "Unable to launch app "
8115                            + cpi.applicationInfo.packageName + "/"
8116                            + cpi.applicationInfo.uid + " for provider "
8117                            + name + ": launching app became null");
8118                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8119                            UserHandle.getUserId(cpi.applicationInfo.uid),
8120                            cpi.applicationInfo.packageName,
8121                            cpi.applicationInfo.uid, name);
8122                    return null;
8123                }
8124                try {
8125                    if (DEBUG_MU) {
8126                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8127                                + cpr.launchingApp);
8128                    }
8129                    if (conn != null) {
8130                        conn.waiting = true;
8131                    }
8132                    cpr.wait();
8133                } catch (InterruptedException ex) {
8134                } finally {
8135                    if (conn != null) {
8136                        conn.waiting = false;
8137                    }
8138                }
8139            }
8140        }
8141        return cpr != null ? cpr.newHolder(conn) : null;
8142    }
8143
8144    @Override
8145    public final ContentProviderHolder getContentProvider(
8146            IApplicationThread caller, String name, int userId, boolean stable) {
8147        enforceNotIsolatedCaller("getContentProvider");
8148        if (caller == null) {
8149            String msg = "null IApplicationThread when getting content provider "
8150                    + name;
8151            Slog.w(TAG, msg);
8152            throw new SecurityException(msg);
8153        }
8154        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8155        // with cross-user grant.
8156        return getContentProviderImpl(caller, name, null, stable, userId);
8157    }
8158
8159    public ContentProviderHolder getContentProviderExternal(
8160            String name, int userId, IBinder token) {
8161        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8162            "Do not have permission in call getContentProviderExternal()");
8163        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8164                false, true, "getContentProvider", null);
8165        return getContentProviderExternalUnchecked(name, token, userId);
8166    }
8167
8168    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8169            IBinder token, int userId) {
8170        return getContentProviderImpl(null, name, token, true, userId);
8171    }
8172
8173    /**
8174     * Drop a content provider from a ProcessRecord's bookkeeping
8175     */
8176    public void removeContentProvider(IBinder connection, boolean stable) {
8177        enforceNotIsolatedCaller("removeContentProvider");
8178        long ident = Binder.clearCallingIdentity();
8179        try {
8180            synchronized (this) {
8181                ContentProviderConnection conn;
8182                try {
8183                    conn = (ContentProviderConnection)connection;
8184                } catch (ClassCastException e) {
8185                    String msg ="removeContentProvider: " + connection
8186                            + " not a ContentProviderConnection";
8187                    Slog.w(TAG, msg);
8188                    throw new IllegalArgumentException(msg);
8189                }
8190                if (conn == null) {
8191                    throw new NullPointerException("connection is null");
8192                }
8193                if (decProviderCountLocked(conn, null, null, stable)) {
8194                    updateOomAdjLocked();
8195                }
8196            }
8197        } finally {
8198            Binder.restoreCallingIdentity(ident);
8199        }
8200    }
8201
8202    public void removeContentProviderExternal(String name, IBinder token) {
8203        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8204            "Do not have permission in call removeContentProviderExternal()");
8205        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8206    }
8207
8208    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8209        synchronized (this) {
8210            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8211            if(cpr == null) {
8212                //remove from mProvidersByClass
8213                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8214                return;
8215            }
8216
8217            //update content provider record entry info
8218            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8219            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8220            if (localCpr.hasExternalProcessHandles()) {
8221                if (localCpr.removeExternalProcessHandleLocked(token)) {
8222                    updateOomAdjLocked();
8223                } else {
8224                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8225                            + " with no external reference for token: "
8226                            + token + ".");
8227                }
8228            } else {
8229                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8230                        + " with no external references.");
8231            }
8232        }
8233    }
8234
8235    public final void publishContentProviders(IApplicationThread caller,
8236            List<ContentProviderHolder> providers) {
8237        if (providers == null) {
8238            return;
8239        }
8240
8241        enforceNotIsolatedCaller("publishContentProviders");
8242        synchronized (this) {
8243            final ProcessRecord r = getRecordForAppLocked(caller);
8244            if (DEBUG_MU)
8245                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8246            if (r == null) {
8247                throw new SecurityException(
8248                        "Unable to find app for caller " + caller
8249                      + " (pid=" + Binder.getCallingPid()
8250                      + ") when publishing content providers");
8251            }
8252
8253            final long origId = Binder.clearCallingIdentity();
8254
8255            final int N = providers.size();
8256            for (int i=0; i<N; i++) {
8257                ContentProviderHolder src = providers.get(i);
8258                if (src == null || src.info == null || src.provider == null) {
8259                    continue;
8260                }
8261                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8262                if (DEBUG_MU)
8263                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8264                if (dst != null) {
8265                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8266                    mProviderMap.putProviderByClass(comp, dst);
8267                    String names[] = dst.info.authority.split(";");
8268                    for (int j = 0; j < names.length; j++) {
8269                        mProviderMap.putProviderByName(names[j], dst);
8270                    }
8271
8272                    int NL = mLaunchingProviders.size();
8273                    int j;
8274                    for (j=0; j<NL; j++) {
8275                        if (mLaunchingProviders.get(j) == dst) {
8276                            mLaunchingProviders.remove(j);
8277                            j--;
8278                            NL--;
8279                        }
8280                    }
8281                    synchronized (dst) {
8282                        dst.provider = src.provider;
8283                        dst.proc = r;
8284                        dst.notifyAll();
8285                    }
8286                    updateOomAdjLocked(r);
8287                }
8288            }
8289
8290            Binder.restoreCallingIdentity(origId);
8291        }
8292    }
8293
8294    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8295        ContentProviderConnection conn;
8296        try {
8297            conn = (ContentProviderConnection)connection;
8298        } catch (ClassCastException e) {
8299            String msg ="refContentProvider: " + connection
8300                    + " not a ContentProviderConnection";
8301            Slog.w(TAG, msg);
8302            throw new IllegalArgumentException(msg);
8303        }
8304        if (conn == null) {
8305            throw new NullPointerException("connection is null");
8306        }
8307
8308        synchronized (this) {
8309            if (stable > 0) {
8310                conn.numStableIncs += stable;
8311            }
8312            stable = conn.stableCount + stable;
8313            if (stable < 0) {
8314                throw new IllegalStateException("stableCount < 0: " + stable);
8315            }
8316
8317            if (unstable > 0) {
8318                conn.numUnstableIncs += unstable;
8319            }
8320            unstable = conn.unstableCount + unstable;
8321            if (unstable < 0) {
8322                throw new IllegalStateException("unstableCount < 0: " + unstable);
8323            }
8324
8325            if ((stable+unstable) <= 0) {
8326                throw new IllegalStateException("ref counts can't go to zero here: stable="
8327                        + stable + " unstable=" + unstable);
8328            }
8329            conn.stableCount = stable;
8330            conn.unstableCount = unstable;
8331            return !conn.dead;
8332        }
8333    }
8334
8335    public void unstableProviderDied(IBinder connection) {
8336        ContentProviderConnection conn;
8337        try {
8338            conn = (ContentProviderConnection)connection;
8339        } catch (ClassCastException e) {
8340            String msg ="refContentProvider: " + connection
8341                    + " not a ContentProviderConnection";
8342            Slog.w(TAG, msg);
8343            throw new IllegalArgumentException(msg);
8344        }
8345        if (conn == null) {
8346            throw new NullPointerException("connection is null");
8347        }
8348
8349        // Safely retrieve the content provider associated with the connection.
8350        IContentProvider provider;
8351        synchronized (this) {
8352            provider = conn.provider.provider;
8353        }
8354
8355        if (provider == null) {
8356            // Um, yeah, we're way ahead of you.
8357            return;
8358        }
8359
8360        // Make sure the caller is being honest with us.
8361        if (provider.asBinder().pingBinder()) {
8362            // Er, no, still looks good to us.
8363            synchronized (this) {
8364                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8365                        + " says " + conn + " died, but we don't agree");
8366                return;
8367            }
8368        }
8369
8370        // Well look at that!  It's dead!
8371        synchronized (this) {
8372            if (conn.provider.provider != provider) {
8373                // But something changed...  good enough.
8374                return;
8375            }
8376
8377            ProcessRecord proc = conn.provider.proc;
8378            if (proc == null || proc.thread == null) {
8379                // Seems like the process is already cleaned up.
8380                return;
8381            }
8382
8383            // As far as we're concerned, this is just like receiving a
8384            // death notification...  just a bit prematurely.
8385            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8386                    + ") early provider death");
8387            final long ident = Binder.clearCallingIdentity();
8388            try {
8389                appDiedLocked(proc, proc.pid, proc.thread);
8390            } finally {
8391                Binder.restoreCallingIdentity(ident);
8392            }
8393        }
8394    }
8395
8396    @Override
8397    public void appNotRespondingViaProvider(IBinder connection) {
8398        enforceCallingPermission(
8399                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8400
8401        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8402        if (conn == null) {
8403            Slog.w(TAG, "ContentProviderConnection is null");
8404            return;
8405        }
8406
8407        final ProcessRecord host = conn.provider.proc;
8408        if (host == null) {
8409            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8410            return;
8411        }
8412
8413        final long token = Binder.clearCallingIdentity();
8414        try {
8415            appNotResponding(host, null, null, false, "ContentProvider not responding");
8416        } finally {
8417            Binder.restoreCallingIdentity(token);
8418        }
8419    }
8420
8421    public final void installSystemProviders() {
8422        List<ProviderInfo> providers;
8423        synchronized (this) {
8424            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8425            providers = generateApplicationProvidersLocked(app);
8426            if (providers != null) {
8427                for (int i=providers.size()-1; i>=0; i--) {
8428                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8429                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8430                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8431                                + ": not system .apk");
8432                        providers.remove(i);
8433                    }
8434                }
8435            }
8436        }
8437        if (providers != null) {
8438            mSystemThread.installSystemProviders(providers);
8439        }
8440
8441        mCoreSettingsObserver = new CoreSettingsObserver(this);
8442
8443        mUsageStatsService.monitorPackages();
8444    }
8445
8446    /**
8447     * Allows app to retrieve the MIME type of a URI without having permission
8448     * to access its content provider.
8449     *
8450     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8451     *
8452     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8453     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8454     */
8455    public String getProviderMimeType(Uri uri, int userId) {
8456        enforceNotIsolatedCaller("getProviderMimeType");
8457        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8458                userId, false, true, "getProviderMimeType", null);
8459        final String name = uri.getAuthority();
8460        final long ident = Binder.clearCallingIdentity();
8461        ContentProviderHolder holder = null;
8462
8463        try {
8464            holder = getContentProviderExternalUnchecked(name, null, userId);
8465            if (holder != null) {
8466                return holder.provider.getType(uri);
8467            }
8468        } catch (RemoteException e) {
8469            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8470            return null;
8471        } finally {
8472            if (holder != null) {
8473                removeContentProviderExternalUnchecked(name, null, userId);
8474            }
8475            Binder.restoreCallingIdentity(ident);
8476        }
8477
8478        return null;
8479    }
8480
8481    // =========================================================
8482    // GLOBAL MANAGEMENT
8483    // =========================================================
8484
8485    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8486            boolean isolated) {
8487        String proc = customProcess != null ? customProcess : info.processName;
8488        BatteryStatsImpl.Uid.Proc ps = null;
8489        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8490        int uid = info.uid;
8491        if (isolated) {
8492            int userId = UserHandle.getUserId(uid);
8493            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8494            while (true) {
8495                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8496                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8497                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8498                }
8499                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8500                mNextIsolatedProcessUid++;
8501                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8502                    // No process for this uid, use it.
8503                    break;
8504                }
8505                stepsLeft--;
8506                if (stepsLeft <= 0) {
8507                    return null;
8508                }
8509            }
8510        }
8511        return new ProcessRecord(stats, info, proc, uid);
8512    }
8513
8514    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8515        ProcessRecord app;
8516        if (!isolated) {
8517            app = getProcessRecordLocked(info.processName, info.uid, true);
8518        } else {
8519            app = null;
8520        }
8521
8522        if (app == null) {
8523            app = newProcessRecordLocked(info, null, isolated);
8524            mProcessNames.put(info.processName, app.uid, app);
8525            if (isolated) {
8526                mIsolatedProcesses.put(app.uid, app);
8527            }
8528            updateLruProcessLocked(app, false, null);
8529            updateOomAdjLocked();
8530        }
8531
8532        // This package really, really can not be stopped.
8533        try {
8534            AppGlobals.getPackageManager().setPackageStoppedState(
8535                    info.packageName, false, UserHandle.getUserId(app.uid));
8536        } catch (RemoteException e) {
8537        } catch (IllegalArgumentException e) {
8538            Slog.w(TAG, "Failed trying to unstop package "
8539                    + info.packageName + ": " + e);
8540        }
8541
8542        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8543                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8544            app.persistent = true;
8545            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8546        }
8547        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8548            mPersistentStartingProcesses.add(app);
8549            startProcessLocked(app, "added application", app.processName);
8550        }
8551
8552        return app;
8553    }
8554
8555    public void unhandledBack() {
8556        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8557                "unhandledBack()");
8558
8559        synchronized(this) {
8560            final long origId = Binder.clearCallingIdentity();
8561            try {
8562                getFocusedStack().unhandledBackLocked();
8563            } finally {
8564                Binder.restoreCallingIdentity(origId);
8565            }
8566        }
8567    }
8568
8569    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8570        enforceNotIsolatedCaller("openContentUri");
8571        final int userId = UserHandle.getCallingUserId();
8572        String name = uri.getAuthority();
8573        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8574        ParcelFileDescriptor pfd = null;
8575        if (cph != null) {
8576            // We record the binder invoker's uid in thread-local storage before
8577            // going to the content provider to open the file.  Later, in the code
8578            // that handles all permissions checks, we look for this uid and use
8579            // that rather than the Activity Manager's own uid.  The effect is that
8580            // we do the check against the caller's permissions even though it looks
8581            // to the content provider like the Activity Manager itself is making
8582            // the request.
8583            sCallerIdentity.set(new Identity(
8584                    Binder.getCallingPid(), Binder.getCallingUid()));
8585            try {
8586                pfd = cph.provider.openFile(null, uri, "r", null);
8587            } catch (FileNotFoundException e) {
8588                // do nothing; pfd will be returned null
8589            } finally {
8590                // Ensure that whatever happens, we clean up the identity state
8591                sCallerIdentity.remove();
8592            }
8593
8594            // We've got the fd now, so we're done with the provider.
8595            removeContentProviderExternalUnchecked(name, null, userId);
8596        } else {
8597            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8598        }
8599        return pfd;
8600    }
8601
8602    // Actually is sleeping or shutting down or whatever else in the future
8603    // is an inactive state.
8604    public boolean isSleepingOrShuttingDown() {
8605        return mSleeping || mShuttingDown;
8606    }
8607
8608    public boolean isSleeping() {
8609        return mSleeping;
8610    }
8611
8612    void goingToSleep() {
8613        synchronized(this) {
8614            mWentToSleep = true;
8615            updateEventDispatchingLocked();
8616            goToSleepIfNeededLocked();
8617        }
8618    }
8619
8620    void finishRunningVoiceLocked() {
8621        if (mRunningVoice) {
8622            mRunningVoice = false;
8623            goToSleepIfNeededLocked();
8624        }
8625    }
8626
8627    void goToSleepIfNeededLocked() {
8628        if (mWentToSleep && !mRunningVoice) {
8629            if (!mSleeping) {
8630                mSleeping = true;
8631                mStackSupervisor.goingToSleepLocked();
8632
8633                // Initialize the wake times of all processes.
8634                checkExcessivePowerUsageLocked(false);
8635                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8636                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8637                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8638            }
8639        }
8640    }
8641
8642    @Override
8643    public boolean shutdown(int timeout) {
8644        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8645                != PackageManager.PERMISSION_GRANTED) {
8646            throw new SecurityException("Requires permission "
8647                    + android.Manifest.permission.SHUTDOWN);
8648        }
8649
8650        boolean timedout = false;
8651
8652        synchronized(this) {
8653            mShuttingDown = true;
8654            updateEventDispatchingLocked();
8655            timedout = mStackSupervisor.shutdownLocked(timeout);
8656        }
8657
8658        mAppOpsService.shutdown();
8659        mUsageStatsService.shutdown();
8660        mBatteryStatsService.shutdown();
8661        synchronized (this) {
8662            mProcessStats.shutdownLocked();
8663        }
8664
8665        return timedout;
8666    }
8667
8668    public final void activitySlept(IBinder token) {
8669        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8670
8671        final long origId = Binder.clearCallingIdentity();
8672
8673        synchronized (this) {
8674            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8675            if (r != null) {
8676                mStackSupervisor.activitySleptLocked(r);
8677            }
8678        }
8679
8680        Binder.restoreCallingIdentity(origId);
8681    }
8682
8683    void logLockScreen(String msg) {
8684        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8685                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8686                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8687                mStackSupervisor.mDismissKeyguardOnNextActivity);
8688    }
8689
8690    private void comeOutOfSleepIfNeededLocked() {
8691        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8692            if (mSleeping) {
8693                mSleeping = false;
8694                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8695            }
8696        }
8697    }
8698
8699    void wakingUp() {
8700        synchronized(this) {
8701            mWentToSleep = false;
8702            updateEventDispatchingLocked();
8703            comeOutOfSleepIfNeededLocked();
8704        }
8705    }
8706
8707    void startRunningVoiceLocked() {
8708        if (!mRunningVoice) {
8709            mRunningVoice = true;
8710            comeOutOfSleepIfNeededLocked();
8711        }
8712    }
8713
8714    private void updateEventDispatchingLocked() {
8715        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8716    }
8717
8718    public void setLockScreenShown(boolean shown) {
8719        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8720                != PackageManager.PERMISSION_GRANTED) {
8721            throw new SecurityException("Requires permission "
8722                    + android.Manifest.permission.DEVICE_POWER);
8723        }
8724
8725        synchronized(this) {
8726            long ident = Binder.clearCallingIdentity();
8727            try {
8728                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8729                mLockScreenShown = shown;
8730                comeOutOfSleepIfNeededLocked();
8731            } finally {
8732                Binder.restoreCallingIdentity(ident);
8733            }
8734        }
8735    }
8736
8737    public void stopAppSwitches() {
8738        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8739                != PackageManager.PERMISSION_GRANTED) {
8740            throw new SecurityException("Requires permission "
8741                    + android.Manifest.permission.STOP_APP_SWITCHES);
8742        }
8743
8744        synchronized(this) {
8745            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8746                    + APP_SWITCH_DELAY_TIME;
8747            mDidAppSwitch = false;
8748            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8749            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8750            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8751        }
8752    }
8753
8754    public void resumeAppSwitches() {
8755        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8756                != PackageManager.PERMISSION_GRANTED) {
8757            throw new SecurityException("Requires permission "
8758                    + android.Manifest.permission.STOP_APP_SWITCHES);
8759        }
8760
8761        synchronized(this) {
8762            // Note that we don't execute any pending app switches... we will
8763            // let those wait until either the timeout, or the next start
8764            // activity request.
8765            mAppSwitchesAllowedTime = 0;
8766        }
8767    }
8768
8769    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8770            String name) {
8771        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8772            return true;
8773        }
8774
8775        final int perm = checkComponentPermission(
8776                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8777                callingUid, -1, true);
8778        if (perm == PackageManager.PERMISSION_GRANTED) {
8779            return true;
8780        }
8781
8782        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8783        return false;
8784    }
8785
8786    public void setDebugApp(String packageName, boolean waitForDebugger,
8787            boolean persistent) {
8788        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8789                "setDebugApp()");
8790
8791        long ident = Binder.clearCallingIdentity();
8792        try {
8793            // Note that this is not really thread safe if there are multiple
8794            // callers into it at the same time, but that's not a situation we
8795            // care about.
8796            if (persistent) {
8797                final ContentResolver resolver = mContext.getContentResolver();
8798                Settings.Global.putString(
8799                    resolver, Settings.Global.DEBUG_APP,
8800                    packageName);
8801                Settings.Global.putInt(
8802                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8803                    waitForDebugger ? 1 : 0);
8804            }
8805
8806            synchronized (this) {
8807                if (!persistent) {
8808                    mOrigDebugApp = mDebugApp;
8809                    mOrigWaitForDebugger = mWaitForDebugger;
8810                }
8811                mDebugApp = packageName;
8812                mWaitForDebugger = waitForDebugger;
8813                mDebugTransient = !persistent;
8814                if (packageName != null) {
8815                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8816                            false, UserHandle.USER_ALL, "set debug app");
8817                }
8818            }
8819        } finally {
8820            Binder.restoreCallingIdentity(ident);
8821        }
8822    }
8823
8824    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8825        synchronized (this) {
8826            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8827            if (!isDebuggable) {
8828                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8829                    throw new SecurityException("Process not debuggable: " + app.packageName);
8830                }
8831            }
8832
8833            mOpenGlTraceApp = processName;
8834        }
8835    }
8836
8837    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8838            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8839        synchronized (this) {
8840            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8841            if (!isDebuggable) {
8842                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8843                    throw new SecurityException("Process not debuggable: " + app.packageName);
8844                }
8845            }
8846            mProfileApp = processName;
8847            mProfileFile = profileFile;
8848            if (mProfileFd != null) {
8849                try {
8850                    mProfileFd.close();
8851                } catch (IOException e) {
8852                }
8853                mProfileFd = null;
8854            }
8855            mProfileFd = profileFd;
8856            mProfileType = 0;
8857            mAutoStopProfiler = autoStopProfiler;
8858        }
8859    }
8860
8861    @Override
8862    public void setAlwaysFinish(boolean enabled) {
8863        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8864                "setAlwaysFinish()");
8865
8866        Settings.Global.putInt(
8867                mContext.getContentResolver(),
8868                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8869
8870        synchronized (this) {
8871            mAlwaysFinishActivities = enabled;
8872        }
8873    }
8874
8875    @Override
8876    public void setActivityController(IActivityController controller) {
8877        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8878                "setActivityController()");
8879        synchronized (this) {
8880            mController = controller;
8881            Watchdog.getInstance().setActivityController(controller);
8882        }
8883    }
8884
8885    @Override
8886    public void setUserIsMonkey(boolean userIsMonkey) {
8887        synchronized (this) {
8888            synchronized (mPidsSelfLocked) {
8889                final int callingPid = Binder.getCallingPid();
8890                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8891                if (precessRecord == null) {
8892                    throw new SecurityException("Unknown process: " + callingPid);
8893                }
8894                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8895                    throw new SecurityException("Only an instrumentation process "
8896                            + "with a UiAutomation can call setUserIsMonkey");
8897                }
8898            }
8899            mUserIsMonkey = userIsMonkey;
8900        }
8901    }
8902
8903    @Override
8904    public boolean isUserAMonkey() {
8905        synchronized (this) {
8906            // If there is a controller also implies the user is a monkey.
8907            return (mUserIsMonkey || mController != null);
8908        }
8909    }
8910
8911    public void requestBugReport() {
8912        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8913        SystemProperties.set("ctl.start", "bugreport");
8914    }
8915
8916    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8917        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8918    }
8919
8920    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8921        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8922            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8923        }
8924        return KEY_DISPATCHING_TIMEOUT;
8925    }
8926
8927    @Override
8928    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8929        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8930                != PackageManager.PERMISSION_GRANTED) {
8931            throw new SecurityException("Requires permission "
8932                    + android.Manifest.permission.FILTER_EVENTS);
8933        }
8934        ProcessRecord proc;
8935        long timeout;
8936        synchronized (this) {
8937            synchronized (mPidsSelfLocked) {
8938                proc = mPidsSelfLocked.get(pid);
8939            }
8940            timeout = getInputDispatchingTimeoutLocked(proc);
8941        }
8942
8943        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8944            return -1;
8945        }
8946
8947        return timeout;
8948    }
8949
8950    /**
8951     * Handle input dispatching timeouts.
8952     * Returns whether input dispatching should be aborted or not.
8953     */
8954    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8955            final ActivityRecord activity, final ActivityRecord parent,
8956            final boolean aboveSystem, String reason) {
8957        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8958                != PackageManager.PERMISSION_GRANTED) {
8959            throw new SecurityException("Requires permission "
8960                    + android.Manifest.permission.FILTER_EVENTS);
8961        }
8962
8963        final String annotation;
8964        if (reason == null) {
8965            annotation = "Input dispatching timed out";
8966        } else {
8967            annotation = "Input dispatching timed out (" + reason + ")";
8968        }
8969
8970        if (proc != null) {
8971            synchronized (this) {
8972                if (proc.debugging) {
8973                    return false;
8974                }
8975
8976                if (mDidDexOpt) {
8977                    // Give more time since we were dexopting.
8978                    mDidDexOpt = false;
8979                    return false;
8980                }
8981
8982                if (proc.instrumentationClass != null) {
8983                    Bundle info = new Bundle();
8984                    info.putString("shortMsg", "keyDispatchingTimedOut");
8985                    info.putString("longMsg", annotation);
8986                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8987                    return true;
8988                }
8989            }
8990            mHandler.post(new Runnable() {
8991                @Override
8992                public void run() {
8993                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8994                }
8995            });
8996        }
8997
8998        return true;
8999    }
9000
9001    public Bundle getAssistContextExtras(int requestType) {
9002        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9003                "getAssistContextExtras()");
9004        PendingAssistExtras pae;
9005        Bundle extras = new Bundle();
9006        synchronized (this) {
9007            ActivityRecord activity = getFocusedStack().mResumedActivity;
9008            if (activity == null) {
9009                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9010                return null;
9011            }
9012            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9013            if (activity.app == null || activity.app.thread == null) {
9014                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9015                return extras;
9016            }
9017            if (activity.app.pid == Binder.getCallingPid()) {
9018                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9019                return extras;
9020            }
9021            pae = new PendingAssistExtras(activity);
9022            try {
9023                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9024                        requestType);
9025                mPendingAssistExtras.add(pae);
9026                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9027            } catch (RemoteException e) {
9028                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9029                return extras;
9030            }
9031        }
9032        synchronized (pae) {
9033            while (!pae.haveResult) {
9034                try {
9035                    pae.wait();
9036                } catch (InterruptedException e) {
9037                }
9038            }
9039            if (pae.result != null) {
9040                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9041            }
9042        }
9043        synchronized (this) {
9044            mPendingAssistExtras.remove(pae);
9045            mHandler.removeCallbacks(pae);
9046        }
9047        return extras;
9048    }
9049
9050    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9051        PendingAssistExtras pae = (PendingAssistExtras)token;
9052        synchronized (pae) {
9053            pae.result = extras;
9054            pae.haveResult = true;
9055            pae.notifyAll();
9056        }
9057    }
9058
9059    public void registerProcessObserver(IProcessObserver observer) {
9060        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9061                "registerProcessObserver()");
9062        synchronized (this) {
9063            mProcessObservers.register(observer);
9064        }
9065    }
9066
9067    @Override
9068    public void unregisterProcessObserver(IProcessObserver observer) {
9069        synchronized (this) {
9070            mProcessObservers.unregister(observer);
9071        }
9072    }
9073
9074    @Override
9075    public boolean convertFromTranslucent(IBinder token) {
9076        final long origId = Binder.clearCallingIdentity();
9077        try {
9078            synchronized (this) {
9079                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9080                if (r == null) {
9081                    return false;
9082                }
9083                if (r.changeWindowTranslucency(true)) {
9084                    mWindowManager.setAppFullscreen(token, true);
9085                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9086                    return true;
9087                }
9088                return false;
9089            }
9090        } finally {
9091            Binder.restoreCallingIdentity(origId);
9092        }
9093    }
9094
9095    @Override
9096    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9097        final long origId = Binder.clearCallingIdentity();
9098        try {
9099            synchronized (this) {
9100                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9101                if (r == null) {
9102                    return false;
9103                }
9104                if (r.changeWindowTranslucency(false)) {
9105                    r.task.stack.convertToTranslucent(r, options);
9106                    mWindowManager.setAppFullscreen(token, false);
9107                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9108                    return true;
9109                }
9110                return false;
9111            }
9112        } finally {
9113            Binder.restoreCallingIdentity(origId);
9114        }
9115    }
9116
9117    @Override
9118    public ActivityOptions getActivityOptions(IBinder token) {
9119        final long origId = Binder.clearCallingIdentity();
9120        try {
9121            synchronized (this) {
9122                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9123                if (r != null) {
9124                    final ActivityOptions activityOptions = r.pendingOptions;
9125                    r.pendingOptions = null;
9126                    return activityOptions;
9127                }
9128                return null;
9129            }
9130        } finally {
9131            Binder.restoreCallingIdentity(origId);
9132        }
9133    }
9134
9135    @Override
9136    public void setImmersive(IBinder token, boolean immersive) {
9137        synchronized(this) {
9138            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9139            if (r == null) {
9140                throw new IllegalArgumentException();
9141            }
9142            r.immersive = immersive;
9143
9144            // update associated state if we're frontmost
9145            if (r == mFocusedActivity) {
9146                if (DEBUG_IMMERSIVE) {
9147                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9148                }
9149                applyUpdateLockStateLocked(r);
9150            }
9151        }
9152    }
9153
9154    @Override
9155    public boolean isImmersive(IBinder token) {
9156        synchronized (this) {
9157            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9158            if (r == null) {
9159                throw new IllegalArgumentException();
9160            }
9161            return r.immersive;
9162        }
9163    }
9164
9165    public boolean isTopActivityImmersive() {
9166        enforceNotIsolatedCaller("startActivity");
9167        synchronized (this) {
9168            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9169            return (r != null) ? r.immersive : false;
9170        }
9171    }
9172
9173    public final void enterSafeMode() {
9174        synchronized(this) {
9175            // It only makes sense to do this before the system is ready
9176            // and started launching other packages.
9177            if (!mSystemReady) {
9178                try {
9179                    AppGlobals.getPackageManager().enterSafeMode();
9180                } catch (RemoteException e) {
9181                }
9182            }
9183
9184            mSafeMode = true;
9185        }
9186    }
9187
9188    public final void showSafeModeOverlay() {
9189        View v = LayoutInflater.from(mContext).inflate(
9190                com.android.internal.R.layout.safe_mode, null);
9191        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9192        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9193        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9194        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9195        lp.gravity = Gravity.BOTTOM | Gravity.START;
9196        lp.format = v.getBackground().getOpacity();
9197        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9198                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9199        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9200        ((WindowManager)mContext.getSystemService(
9201                Context.WINDOW_SERVICE)).addView(v, lp);
9202    }
9203
9204    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9205        if (!(sender instanceof PendingIntentRecord)) {
9206            return;
9207        }
9208        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9209        synchronized (stats) {
9210            if (mBatteryStatsService.isOnBattery()) {
9211                mBatteryStatsService.enforceCallingPermission();
9212                PendingIntentRecord rec = (PendingIntentRecord)sender;
9213                int MY_UID = Binder.getCallingUid();
9214                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9215                BatteryStatsImpl.Uid.Pkg pkg =
9216                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9217                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9218                pkg.incWakeupsLocked();
9219            }
9220        }
9221    }
9222
9223    public boolean killPids(int[] pids, String pReason, boolean secure) {
9224        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9225            throw new SecurityException("killPids only available to the system");
9226        }
9227        String reason = (pReason == null) ? "Unknown" : pReason;
9228        // XXX Note: don't acquire main activity lock here, because the window
9229        // manager calls in with its locks held.
9230
9231        boolean killed = false;
9232        synchronized (mPidsSelfLocked) {
9233            int[] types = new int[pids.length];
9234            int worstType = 0;
9235            for (int i=0; i<pids.length; i++) {
9236                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9237                if (proc != null) {
9238                    int type = proc.setAdj;
9239                    types[i] = type;
9240                    if (type > worstType) {
9241                        worstType = type;
9242                    }
9243                }
9244            }
9245
9246            // If the worst oom_adj is somewhere in the cached proc LRU range,
9247            // then constrain it so we will kill all cached procs.
9248            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9249                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9250                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9251            }
9252
9253            // If this is not a secure call, don't let it kill processes that
9254            // are important.
9255            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9256                worstType = ProcessList.SERVICE_ADJ;
9257            }
9258
9259            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9260            for (int i=0; i<pids.length; i++) {
9261                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9262                if (proc == null) {
9263                    continue;
9264                }
9265                int adj = proc.setAdj;
9266                if (adj >= worstType && !proc.killedByAm) {
9267                    killUnneededProcessLocked(proc, reason);
9268                    killed = true;
9269                }
9270            }
9271        }
9272        return killed;
9273    }
9274
9275    @Override
9276    public void killUid(int uid, String reason) {
9277        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9278            throw new SecurityException("killUid only available to the system");
9279        }
9280        synchronized (this) {
9281            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9282                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9283                    reason != null ? reason : "kill uid");
9284        }
9285    }
9286
9287    @Override
9288    public boolean killProcessesBelowForeground(String reason) {
9289        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9290            throw new SecurityException("killProcessesBelowForeground() only available to system");
9291        }
9292
9293        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9294    }
9295
9296    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9297        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9298            throw new SecurityException("killProcessesBelowAdj() only available to system");
9299        }
9300
9301        boolean killed = false;
9302        synchronized (mPidsSelfLocked) {
9303            final int size = mPidsSelfLocked.size();
9304            for (int i = 0; i < size; i++) {
9305                final int pid = mPidsSelfLocked.keyAt(i);
9306                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9307                if (proc == null) continue;
9308
9309                final int adj = proc.setAdj;
9310                if (adj > belowAdj && !proc.killedByAm) {
9311                    killUnneededProcessLocked(proc, reason);
9312                    killed = true;
9313                }
9314            }
9315        }
9316        return killed;
9317    }
9318
9319    @Override
9320    public void hang(final IBinder who, boolean allowRestart) {
9321        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9322                != PackageManager.PERMISSION_GRANTED) {
9323            throw new SecurityException("Requires permission "
9324                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9325        }
9326
9327        final IBinder.DeathRecipient death = new DeathRecipient() {
9328            @Override
9329            public void binderDied() {
9330                synchronized (this) {
9331                    notifyAll();
9332                }
9333            }
9334        };
9335
9336        try {
9337            who.linkToDeath(death, 0);
9338        } catch (RemoteException e) {
9339            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9340            return;
9341        }
9342
9343        synchronized (this) {
9344            Watchdog.getInstance().setAllowRestart(allowRestart);
9345            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9346            synchronized (death) {
9347                while (who.isBinderAlive()) {
9348                    try {
9349                        death.wait();
9350                    } catch (InterruptedException e) {
9351                    }
9352                }
9353            }
9354            Watchdog.getInstance().setAllowRestart(true);
9355        }
9356    }
9357
9358    @Override
9359    public void restart() {
9360        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9361                != PackageManager.PERMISSION_GRANTED) {
9362            throw new SecurityException("Requires permission "
9363                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9364        }
9365
9366        Log.i(TAG, "Sending shutdown broadcast...");
9367
9368        BroadcastReceiver br = new BroadcastReceiver() {
9369            @Override public void onReceive(Context context, Intent intent) {
9370                // Now the broadcast is done, finish up the low-level shutdown.
9371                Log.i(TAG, "Shutting down activity manager...");
9372                shutdown(10000);
9373                Log.i(TAG, "Shutdown complete, restarting!");
9374                Process.killProcess(Process.myPid());
9375                System.exit(10);
9376            }
9377        };
9378
9379        // First send the high-level shut down broadcast.
9380        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9381        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9382        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9383        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9384        mContext.sendOrderedBroadcastAsUser(intent,
9385                UserHandle.ALL, null, br, mHandler, 0, null, null);
9386        */
9387        br.onReceive(mContext, intent);
9388    }
9389
9390    private long getLowRamTimeSinceIdle(long now) {
9391        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9392    }
9393
9394    @Override
9395    public void performIdleMaintenance() {
9396        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9397                != PackageManager.PERMISSION_GRANTED) {
9398            throw new SecurityException("Requires permission "
9399                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9400        }
9401
9402        synchronized (this) {
9403            final long now = SystemClock.uptimeMillis();
9404            final long timeSinceLastIdle = now - mLastIdleTime;
9405            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9406            mLastIdleTime = now;
9407            mLowRamTimeSinceLastIdle = 0;
9408            if (mLowRamStartTime != 0) {
9409                mLowRamStartTime = now;
9410            }
9411
9412            StringBuilder sb = new StringBuilder(128);
9413            sb.append("Idle maintenance over ");
9414            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9415            sb.append(" low RAM for ");
9416            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9417            Slog.i(TAG, sb.toString());
9418
9419            // If at least 1/3 of our time since the last idle period has been spent
9420            // with RAM low, then we want to kill processes.
9421            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9422
9423            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9424                ProcessRecord proc = mLruProcesses.get(i);
9425                if (proc.notCachedSinceIdle) {
9426                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9427                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9428                        if (doKilling && proc.initialIdlePss != 0
9429                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9430                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9431                                    + " from " + proc.initialIdlePss + ")");
9432                        }
9433                    }
9434                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9435                    proc.notCachedSinceIdle = true;
9436                    proc.initialIdlePss = 0;
9437                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9438                            isSleeping(), now);
9439                }
9440            }
9441
9442            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9443            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9444        }
9445    }
9446
9447    private void retrieveSettings() {
9448        final ContentResolver resolver = mContext.getContentResolver();
9449        String debugApp = Settings.Global.getString(
9450            resolver, Settings.Global.DEBUG_APP);
9451        boolean waitForDebugger = Settings.Global.getInt(
9452            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9453        boolean alwaysFinishActivities = Settings.Global.getInt(
9454            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9455        boolean forceRtl = Settings.Global.getInt(
9456                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9457        // Transfer any global setting for forcing RTL layout, into a System Property
9458        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9459
9460        Configuration configuration = new Configuration();
9461        Settings.System.getConfiguration(resolver, configuration);
9462        if (forceRtl) {
9463            // This will take care of setting the correct layout direction flags
9464            configuration.setLayoutDirection(configuration.locale);
9465        }
9466
9467        synchronized (this) {
9468            mDebugApp = mOrigDebugApp = debugApp;
9469            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9470            mAlwaysFinishActivities = alwaysFinishActivities;
9471            // This happens before any activities are started, so we can
9472            // change mConfiguration in-place.
9473            updateConfigurationLocked(configuration, null, false, true);
9474            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9475        }
9476    }
9477
9478    public boolean testIsSystemReady() {
9479        // no need to synchronize(this) just to read & return the value
9480        return mSystemReady;
9481    }
9482
9483    private static File getCalledPreBootReceiversFile() {
9484        File dataDir = Environment.getDataDirectory();
9485        File systemDir = new File(dataDir, "system");
9486        File fname = new File(systemDir, "called_pre_boots.dat");
9487        return fname;
9488    }
9489
9490    static final int LAST_DONE_VERSION = 10000;
9491
9492    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9493        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9494        File file = getCalledPreBootReceiversFile();
9495        FileInputStream fis = null;
9496        try {
9497            fis = new FileInputStream(file);
9498            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9499            int fvers = dis.readInt();
9500            if (fvers == LAST_DONE_VERSION) {
9501                String vers = dis.readUTF();
9502                String codename = dis.readUTF();
9503                String build = dis.readUTF();
9504                if (android.os.Build.VERSION.RELEASE.equals(vers)
9505                        && android.os.Build.VERSION.CODENAME.equals(codename)
9506                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9507                    int num = dis.readInt();
9508                    while (num > 0) {
9509                        num--;
9510                        String pkg = dis.readUTF();
9511                        String cls = dis.readUTF();
9512                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9513                    }
9514                }
9515            }
9516        } catch (FileNotFoundException e) {
9517        } catch (IOException e) {
9518            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9519        } finally {
9520            if (fis != null) {
9521                try {
9522                    fis.close();
9523                } catch (IOException e) {
9524                }
9525            }
9526        }
9527        return lastDoneReceivers;
9528    }
9529
9530    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9531        File file = getCalledPreBootReceiversFile();
9532        FileOutputStream fos = null;
9533        DataOutputStream dos = null;
9534        try {
9535            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9536            fos = new FileOutputStream(file);
9537            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9538            dos.writeInt(LAST_DONE_VERSION);
9539            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9540            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9541            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9542            dos.writeInt(list.size());
9543            for (int i=0; i<list.size(); i++) {
9544                dos.writeUTF(list.get(i).getPackageName());
9545                dos.writeUTF(list.get(i).getClassName());
9546            }
9547        } catch (IOException e) {
9548            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9549            file.delete();
9550        } finally {
9551            FileUtils.sync(fos);
9552            if (dos != null) {
9553                try {
9554                    dos.close();
9555                } catch (IOException e) {
9556                    // TODO Auto-generated catch block
9557                    e.printStackTrace();
9558                }
9559            }
9560        }
9561    }
9562
9563    public void systemReady(final Runnable goingCallback) {
9564        synchronized(this) {
9565            if (mSystemReady) {
9566                if (goingCallback != null) goingCallback.run();
9567                return;
9568            }
9569
9570            // Check to see if there are any update receivers to run.
9571            if (!mDidUpdate) {
9572                if (mWaitingUpdate) {
9573                    return;
9574                }
9575                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9576                List<ResolveInfo> ris = null;
9577                try {
9578                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9579                            intent, null, 0, 0);
9580                } catch (RemoteException e) {
9581                }
9582                if (ris != null) {
9583                    for (int i=ris.size()-1; i>=0; i--) {
9584                        if ((ris.get(i).activityInfo.applicationInfo.flags
9585                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9586                            ris.remove(i);
9587                        }
9588                    }
9589                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9590
9591                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9592
9593                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9594                    for (int i=0; i<ris.size(); i++) {
9595                        ActivityInfo ai = ris.get(i).activityInfo;
9596                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9597                        if (lastDoneReceivers.contains(comp)) {
9598                            // We already did the pre boot receiver for this app with the current
9599                            // platform version, so don't do it again...
9600                            ris.remove(i);
9601                            i--;
9602                            // ...however, do keep it as one that has been done, so we don't
9603                            // forget about it when rewriting the file of last done receivers.
9604                            doneReceivers.add(comp);
9605                        }
9606                    }
9607
9608                    final int[] users = getUsersLocked();
9609                    for (int i=0; i<ris.size(); i++) {
9610                        ActivityInfo ai = ris.get(i).activityInfo;
9611                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9612                        doneReceivers.add(comp);
9613                        intent.setComponent(comp);
9614                        for (int j=0; j<users.length; j++) {
9615                            IIntentReceiver finisher = null;
9616                            if (i == ris.size()-1 && j == users.length-1) {
9617                                finisher = new IIntentReceiver.Stub() {
9618                                    public void performReceive(Intent intent, int resultCode,
9619                                            String data, Bundle extras, boolean ordered,
9620                                            boolean sticky, int sendingUser) {
9621                                        // The raw IIntentReceiver interface is called
9622                                        // with the AM lock held, so redispatch to
9623                                        // execute our code without the lock.
9624                                        mHandler.post(new Runnable() {
9625                                            public void run() {
9626                                                synchronized (ActivityManagerService.this) {
9627                                                    mDidUpdate = true;
9628                                                }
9629                                                writeLastDonePreBootReceivers(doneReceivers);
9630                                                showBootMessage(mContext.getText(
9631                                                        R.string.android_upgrading_complete),
9632                                                        false);
9633                                                systemReady(goingCallback);
9634                                            }
9635                                        });
9636                                    }
9637                                };
9638                            }
9639                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9640                                    + " for user " + users[j]);
9641                            broadcastIntentLocked(null, null, intent, null, finisher,
9642                                    0, null, null, null, AppOpsManager.OP_NONE,
9643                                    true, false, MY_PID, Process.SYSTEM_UID,
9644                                    users[j]);
9645                            if (finisher != null) {
9646                                mWaitingUpdate = true;
9647                            }
9648                        }
9649                    }
9650                }
9651                if (mWaitingUpdate) {
9652                    return;
9653                }
9654                mDidUpdate = true;
9655            }
9656
9657            mAppOpsService.systemReady();
9658            mUsageStatsService.systemReady();
9659            mSystemReady = true;
9660        }
9661
9662        ArrayList<ProcessRecord> procsToKill = null;
9663        synchronized(mPidsSelfLocked) {
9664            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9665                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9666                if (!isAllowedWhileBooting(proc.info)){
9667                    if (procsToKill == null) {
9668                        procsToKill = new ArrayList<ProcessRecord>();
9669                    }
9670                    procsToKill.add(proc);
9671                }
9672            }
9673        }
9674
9675        synchronized(this) {
9676            if (procsToKill != null) {
9677                for (int i=procsToKill.size()-1; i>=0; i--) {
9678                    ProcessRecord proc = procsToKill.get(i);
9679                    Slog.i(TAG, "Removing system update proc: " + proc);
9680                    removeProcessLocked(proc, true, false, "system update done");
9681                }
9682            }
9683
9684            // Now that we have cleaned up any update processes, we
9685            // are ready to start launching real processes and know that
9686            // we won't trample on them any more.
9687            mProcessesReady = true;
9688        }
9689
9690        Slog.i(TAG, "System now ready");
9691        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9692            SystemClock.uptimeMillis());
9693
9694        synchronized(this) {
9695            // Make sure we have no pre-ready processes sitting around.
9696
9697            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9698                ResolveInfo ri = mContext.getPackageManager()
9699                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9700                                STOCK_PM_FLAGS);
9701                CharSequence errorMsg = null;
9702                if (ri != null) {
9703                    ActivityInfo ai = ri.activityInfo;
9704                    ApplicationInfo app = ai.applicationInfo;
9705                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9706                        mTopAction = Intent.ACTION_FACTORY_TEST;
9707                        mTopData = null;
9708                        mTopComponent = new ComponentName(app.packageName,
9709                                ai.name);
9710                    } else {
9711                        errorMsg = mContext.getResources().getText(
9712                                com.android.internal.R.string.factorytest_not_system);
9713                    }
9714                } else {
9715                    errorMsg = mContext.getResources().getText(
9716                            com.android.internal.R.string.factorytest_no_action);
9717                }
9718                if (errorMsg != null) {
9719                    mTopAction = null;
9720                    mTopData = null;
9721                    mTopComponent = null;
9722                    Message msg = Message.obtain();
9723                    msg.what = SHOW_FACTORY_ERROR_MSG;
9724                    msg.getData().putCharSequence("msg", errorMsg);
9725                    mHandler.sendMessage(msg);
9726                }
9727            }
9728        }
9729
9730        retrieveSettings();
9731
9732        synchronized (this) {
9733            readGrantedUriPermissionsLocked();
9734        }
9735
9736        if (goingCallback != null) goingCallback.run();
9737
9738        mSystemServiceManager.startUser(mCurrentUserId);
9739
9740        synchronized (this) {
9741            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9742                try {
9743                    List apps = AppGlobals.getPackageManager().
9744                        getPersistentApplications(STOCK_PM_FLAGS);
9745                    if (apps != null) {
9746                        int N = apps.size();
9747                        int i;
9748                        for (i=0; i<N; i++) {
9749                            ApplicationInfo info
9750                                = (ApplicationInfo)apps.get(i);
9751                            if (info != null &&
9752                                    !info.packageName.equals("android")) {
9753                                addAppLocked(info, false);
9754                            }
9755                        }
9756                    }
9757                } catch (RemoteException ex) {
9758                    // pm is in same process, this will never happen.
9759                }
9760            }
9761
9762            // Start up initial activity.
9763            mBooting = true;
9764
9765            try {
9766                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9767                    Message msg = Message.obtain();
9768                    msg.what = SHOW_UID_ERROR_MSG;
9769                    mHandler.sendMessage(msg);
9770                }
9771            } catch (RemoteException e) {
9772            }
9773
9774            long ident = Binder.clearCallingIdentity();
9775            try {
9776                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9777                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9778                        | Intent.FLAG_RECEIVER_FOREGROUND);
9779                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9780                broadcastIntentLocked(null, null, intent,
9781                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9782                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9783                intent = new Intent(Intent.ACTION_USER_STARTING);
9784                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9785                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9786                broadcastIntentLocked(null, null, intent,
9787                        null, new IIntentReceiver.Stub() {
9788                            @Override
9789                            public void performReceive(Intent intent, int resultCode, String data,
9790                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9791                                    throws RemoteException {
9792                            }
9793                        }, 0, null, null,
9794                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9795                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9796            } catch (Throwable t) {
9797                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9798            } finally {
9799                Binder.restoreCallingIdentity(ident);
9800            }
9801            mStackSupervisor.resumeTopActivitiesLocked();
9802            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9803        }
9804    }
9805
9806    private boolean makeAppCrashingLocked(ProcessRecord app,
9807            String shortMsg, String longMsg, String stackTrace) {
9808        app.crashing = true;
9809        app.crashingReport = generateProcessError(app,
9810                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9811        startAppProblemLocked(app);
9812        app.stopFreezingAllLocked();
9813        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9814    }
9815
9816    private void makeAppNotRespondingLocked(ProcessRecord app,
9817            String activity, String shortMsg, String longMsg) {
9818        app.notResponding = true;
9819        app.notRespondingReport = generateProcessError(app,
9820                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9821                activity, shortMsg, longMsg, null);
9822        startAppProblemLocked(app);
9823        app.stopFreezingAllLocked();
9824    }
9825
9826    /**
9827     * Generate a process error record, suitable for attachment to a ProcessRecord.
9828     *
9829     * @param app The ProcessRecord in which the error occurred.
9830     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9831     *                      ActivityManager.AppErrorStateInfo
9832     * @param activity The activity associated with the crash, if known.
9833     * @param shortMsg Short message describing the crash.
9834     * @param longMsg Long message describing the crash.
9835     * @param stackTrace Full crash stack trace, may be null.
9836     *
9837     * @return Returns a fully-formed AppErrorStateInfo record.
9838     */
9839    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9840            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9841        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9842
9843        report.condition = condition;
9844        report.processName = app.processName;
9845        report.pid = app.pid;
9846        report.uid = app.info.uid;
9847        report.tag = activity;
9848        report.shortMsg = shortMsg;
9849        report.longMsg = longMsg;
9850        report.stackTrace = stackTrace;
9851
9852        return report;
9853    }
9854
9855    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9856        synchronized (this) {
9857            app.crashing = false;
9858            app.crashingReport = null;
9859            app.notResponding = false;
9860            app.notRespondingReport = null;
9861            if (app.anrDialog == fromDialog) {
9862                app.anrDialog = null;
9863            }
9864            if (app.waitDialog == fromDialog) {
9865                app.waitDialog = null;
9866            }
9867            if (app.pid > 0 && app.pid != MY_PID) {
9868                handleAppCrashLocked(app, null, null, null);
9869                killUnneededProcessLocked(app, "user request after error");
9870            }
9871        }
9872    }
9873
9874    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9875            String stackTrace) {
9876        long now = SystemClock.uptimeMillis();
9877
9878        Long crashTime;
9879        if (!app.isolated) {
9880            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9881        } else {
9882            crashTime = null;
9883        }
9884        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9885            // This process loses!
9886            Slog.w(TAG, "Process " + app.info.processName
9887                    + " has crashed too many times: killing!");
9888            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9889                    app.userId, app.info.processName, app.uid);
9890            mStackSupervisor.handleAppCrashLocked(app);
9891            if (!app.persistent) {
9892                // We don't want to start this process again until the user
9893                // explicitly does so...  but for persistent process, we really
9894                // need to keep it running.  If a persistent process is actually
9895                // repeatedly crashing, then badness for everyone.
9896                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9897                        app.info.processName);
9898                if (!app.isolated) {
9899                    // XXX We don't have a way to mark isolated processes
9900                    // as bad, since they don't have a peristent identity.
9901                    mBadProcesses.put(app.info.processName, app.uid,
9902                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9903                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9904                }
9905                app.bad = true;
9906                app.removed = true;
9907                // Don't let services in this process be restarted and potentially
9908                // annoy the user repeatedly.  Unless it is persistent, since those
9909                // processes run critical code.
9910                removeProcessLocked(app, false, false, "crash");
9911                mStackSupervisor.resumeTopActivitiesLocked();
9912                return false;
9913            }
9914            mStackSupervisor.resumeTopActivitiesLocked();
9915        } else {
9916            mStackSupervisor.finishTopRunningActivityLocked(app);
9917        }
9918
9919        // Bump up the crash count of any services currently running in the proc.
9920        for (int i=app.services.size()-1; i>=0; i--) {
9921            // Any services running in the application need to be placed
9922            // back in the pending list.
9923            ServiceRecord sr = app.services.valueAt(i);
9924            sr.crashCount++;
9925        }
9926
9927        // If the crashing process is what we consider to be the "home process" and it has been
9928        // replaced by a third-party app, clear the package preferred activities from packages
9929        // with a home activity running in the process to prevent a repeatedly crashing app
9930        // from blocking the user to manually clear the list.
9931        final ArrayList<ActivityRecord> activities = app.activities;
9932        if (app == mHomeProcess && activities.size() > 0
9933                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9934            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9935                final ActivityRecord r = activities.get(activityNdx);
9936                if (r.isHomeActivity()) {
9937                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9938                    try {
9939                        ActivityThread.getPackageManager()
9940                                .clearPackagePreferredActivities(r.packageName);
9941                    } catch (RemoteException c) {
9942                        // pm is in same process, this will never happen.
9943                    }
9944                }
9945            }
9946        }
9947
9948        if (!app.isolated) {
9949            // XXX Can't keep track of crash times for isolated processes,
9950            // because they don't have a perisistent identity.
9951            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9952        }
9953
9954        return true;
9955    }
9956
9957    void startAppProblemLocked(ProcessRecord app) {
9958        if (app.userId == mCurrentUserId) {
9959            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9960                    mContext, app.info.packageName, app.info.flags);
9961        } else {
9962            // If this app is not running under the current user, then we
9963            // can't give it a report button because that would require
9964            // launching the report UI under a different user.
9965            app.errorReportReceiver = null;
9966        }
9967        skipCurrentReceiverLocked(app);
9968    }
9969
9970    void skipCurrentReceiverLocked(ProcessRecord app) {
9971        for (BroadcastQueue queue : mBroadcastQueues) {
9972            queue.skipCurrentReceiverLocked(app);
9973        }
9974    }
9975
9976    /**
9977     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9978     * The application process will exit immediately after this call returns.
9979     * @param app object of the crashing app, null for the system server
9980     * @param crashInfo describing the exception
9981     */
9982    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9983        ProcessRecord r = findAppProcess(app, "Crash");
9984        final String processName = app == null ? "system_server"
9985                : (r == null ? "unknown" : r.processName);
9986
9987        handleApplicationCrashInner("crash", r, processName, crashInfo);
9988    }
9989
9990    /* Native crash reporting uses this inner version because it needs to be somewhat
9991     * decoupled from the AM-managed cleanup lifecycle
9992     */
9993    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9994            ApplicationErrorReport.CrashInfo crashInfo) {
9995        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9996                UserHandle.getUserId(Binder.getCallingUid()), processName,
9997                r == null ? -1 : r.info.flags,
9998                crashInfo.exceptionClassName,
9999                crashInfo.exceptionMessage,
10000                crashInfo.throwFileName,
10001                crashInfo.throwLineNumber);
10002
10003        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10004
10005        crashApplication(r, crashInfo);
10006    }
10007
10008    public void handleApplicationStrictModeViolation(
10009            IBinder app,
10010            int violationMask,
10011            StrictMode.ViolationInfo info) {
10012        ProcessRecord r = findAppProcess(app, "StrictMode");
10013        if (r == null) {
10014            return;
10015        }
10016
10017        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10018            Integer stackFingerprint = info.hashCode();
10019            boolean logIt = true;
10020            synchronized (mAlreadyLoggedViolatedStacks) {
10021                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10022                    logIt = false;
10023                    // TODO: sub-sample into EventLog for these, with
10024                    // the info.durationMillis?  Then we'd get
10025                    // the relative pain numbers, without logging all
10026                    // the stack traces repeatedly.  We'd want to do
10027                    // likewise in the client code, which also does
10028                    // dup suppression, before the Binder call.
10029                } else {
10030                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10031                        mAlreadyLoggedViolatedStacks.clear();
10032                    }
10033                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10034                }
10035            }
10036            if (logIt) {
10037                logStrictModeViolationToDropBox(r, info);
10038            }
10039        }
10040
10041        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10042            AppErrorResult result = new AppErrorResult();
10043            synchronized (this) {
10044                final long origId = Binder.clearCallingIdentity();
10045
10046                Message msg = Message.obtain();
10047                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10048                HashMap<String, Object> data = new HashMap<String, Object>();
10049                data.put("result", result);
10050                data.put("app", r);
10051                data.put("violationMask", violationMask);
10052                data.put("info", info);
10053                msg.obj = data;
10054                mHandler.sendMessage(msg);
10055
10056                Binder.restoreCallingIdentity(origId);
10057            }
10058            int res = result.get();
10059            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10060        }
10061    }
10062
10063    // Depending on the policy in effect, there could be a bunch of
10064    // these in quick succession so we try to batch these together to
10065    // minimize disk writes, number of dropbox entries, and maximize
10066    // compression, by having more fewer, larger records.
10067    private void logStrictModeViolationToDropBox(
10068            ProcessRecord process,
10069            StrictMode.ViolationInfo info) {
10070        if (info == null) {
10071            return;
10072        }
10073        final boolean isSystemApp = process == null ||
10074                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10075                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10076        final String processName = process == null ? "unknown" : process.processName;
10077        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10078        final DropBoxManager dbox = (DropBoxManager)
10079                mContext.getSystemService(Context.DROPBOX_SERVICE);
10080
10081        // Exit early if the dropbox isn't configured to accept this report type.
10082        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10083
10084        boolean bufferWasEmpty;
10085        boolean needsFlush;
10086        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10087        synchronized (sb) {
10088            bufferWasEmpty = sb.length() == 0;
10089            appendDropBoxProcessHeaders(process, processName, sb);
10090            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10091            sb.append("System-App: ").append(isSystemApp).append("\n");
10092            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10093            if (info.violationNumThisLoop != 0) {
10094                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10095            }
10096            if (info.numAnimationsRunning != 0) {
10097                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10098            }
10099            if (info.broadcastIntentAction != null) {
10100                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10101            }
10102            if (info.durationMillis != -1) {
10103                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10104            }
10105            if (info.numInstances != -1) {
10106                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10107            }
10108            if (info.tags != null) {
10109                for (String tag : info.tags) {
10110                    sb.append("Span-Tag: ").append(tag).append("\n");
10111                }
10112            }
10113            sb.append("\n");
10114            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10115                sb.append(info.crashInfo.stackTrace);
10116            }
10117            sb.append("\n");
10118
10119            // Only buffer up to ~64k.  Various logging bits truncate
10120            // things at 128k.
10121            needsFlush = (sb.length() > 64 * 1024);
10122        }
10123
10124        // Flush immediately if the buffer's grown too large, or this
10125        // is a non-system app.  Non-system apps are isolated with a
10126        // different tag & policy and not batched.
10127        //
10128        // Batching is useful during internal testing with
10129        // StrictMode settings turned up high.  Without batching,
10130        // thousands of separate files could be created on boot.
10131        if (!isSystemApp || needsFlush) {
10132            new Thread("Error dump: " + dropboxTag) {
10133                @Override
10134                public void run() {
10135                    String report;
10136                    synchronized (sb) {
10137                        report = sb.toString();
10138                        sb.delete(0, sb.length());
10139                        sb.trimToSize();
10140                    }
10141                    if (report.length() != 0) {
10142                        dbox.addText(dropboxTag, report);
10143                    }
10144                }
10145            }.start();
10146            return;
10147        }
10148
10149        // System app batching:
10150        if (!bufferWasEmpty) {
10151            // An existing dropbox-writing thread is outstanding, so
10152            // we don't need to start it up.  The existing thread will
10153            // catch the buffer appends we just did.
10154            return;
10155        }
10156
10157        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10158        // (After this point, we shouldn't access AMS internal data structures.)
10159        new Thread("Error dump: " + dropboxTag) {
10160            @Override
10161            public void run() {
10162                // 5 second sleep to let stacks arrive and be batched together
10163                try {
10164                    Thread.sleep(5000);  // 5 seconds
10165                } catch (InterruptedException e) {}
10166
10167                String errorReport;
10168                synchronized (mStrictModeBuffer) {
10169                    errorReport = mStrictModeBuffer.toString();
10170                    if (errorReport.length() == 0) {
10171                        return;
10172                    }
10173                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10174                    mStrictModeBuffer.trimToSize();
10175                }
10176                dbox.addText(dropboxTag, errorReport);
10177            }
10178        }.start();
10179    }
10180
10181    /**
10182     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10183     * @param app object of the crashing app, null for the system server
10184     * @param tag reported by the caller
10185     * @param crashInfo describing the context of the error
10186     * @return true if the process should exit immediately (WTF is fatal)
10187     */
10188    public boolean handleApplicationWtf(IBinder app, String tag,
10189            ApplicationErrorReport.CrashInfo crashInfo) {
10190        ProcessRecord r = findAppProcess(app, "WTF");
10191        final String processName = app == null ? "system_server"
10192                : (r == null ? "unknown" : r.processName);
10193
10194        EventLog.writeEvent(EventLogTags.AM_WTF,
10195                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10196                processName,
10197                r == null ? -1 : r.info.flags,
10198                tag, crashInfo.exceptionMessage);
10199
10200        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10201
10202        if (r != null && r.pid != Process.myPid() &&
10203                Settings.Global.getInt(mContext.getContentResolver(),
10204                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10205            crashApplication(r, crashInfo);
10206            return true;
10207        } else {
10208            return false;
10209        }
10210    }
10211
10212    /**
10213     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10214     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10215     */
10216    private ProcessRecord findAppProcess(IBinder app, String reason) {
10217        if (app == null) {
10218            return null;
10219        }
10220
10221        synchronized (this) {
10222            final int NP = mProcessNames.getMap().size();
10223            for (int ip=0; ip<NP; ip++) {
10224                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10225                final int NA = apps.size();
10226                for (int ia=0; ia<NA; ia++) {
10227                    ProcessRecord p = apps.valueAt(ia);
10228                    if (p.thread != null && p.thread.asBinder() == app) {
10229                        return p;
10230                    }
10231                }
10232            }
10233
10234            Slog.w(TAG, "Can't find mystery application for " + reason
10235                    + " from pid=" + Binder.getCallingPid()
10236                    + " uid=" + Binder.getCallingUid() + ": " + app);
10237            return null;
10238        }
10239    }
10240
10241    /**
10242     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10243     * to append various headers to the dropbox log text.
10244     */
10245    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10246            StringBuilder sb) {
10247        // Watchdog thread ends up invoking this function (with
10248        // a null ProcessRecord) to add the stack file to dropbox.
10249        // Do not acquire a lock on this (am) in such cases, as it
10250        // could cause a potential deadlock, if and when watchdog
10251        // is invoked due to unavailability of lock on am and it
10252        // would prevent watchdog from killing system_server.
10253        if (process == null) {
10254            sb.append("Process: ").append(processName).append("\n");
10255            return;
10256        }
10257        // Note: ProcessRecord 'process' is guarded by the service
10258        // instance.  (notably process.pkgList, which could otherwise change
10259        // concurrently during execution of this method)
10260        synchronized (this) {
10261            sb.append("Process: ").append(processName).append("\n");
10262            int flags = process.info.flags;
10263            IPackageManager pm = AppGlobals.getPackageManager();
10264            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10265            for (int ip=0; ip<process.pkgList.size(); ip++) {
10266                String pkg = process.pkgList.keyAt(ip);
10267                sb.append("Package: ").append(pkg);
10268                try {
10269                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10270                    if (pi != null) {
10271                        sb.append(" v").append(pi.versionCode);
10272                        if (pi.versionName != null) {
10273                            sb.append(" (").append(pi.versionName).append(")");
10274                        }
10275                    }
10276                } catch (RemoteException e) {
10277                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10278                }
10279                sb.append("\n");
10280            }
10281        }
10282    }
10283
10284    private static String processClass(ProcessRecord process) {
10285        if (process == null || process.pid == MY_PID) {
10286            return "system_server";
10287        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10288            return "system_app";
10289        } else {
10290            return "data_app";
10291        }
10292    }
10293
10294    /**
10295     * Write a description of an error (crash, WTF, ANR) to the drop box.
10296     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10297     * @param process which caused the error, null means the system server
10298     * @param activity which triggered the error, null if unknown
10299     * @param parent activity related to the error, null if unknown
10300     * @param subject line related to the error, null if absent
10301     * @param report in long form describing the error, null if absent
10302     * @param logFile to include in the report, null if none
10303     * @param crashInfo giving an application stack trace, null if absent
10304     */
10305    public void addErrorToDropBox(String eventType,
10306            ProcessRecord process, String processName, ActivityRecord activity,
10307            ActivityRecord parent, String subject,
10308            final String report, final File logFile,
10309            final ApplicationErrorReport.CrashInfo crashInfo) {
10310        // NOTE -- this must never acquire the ActivityManagerService lock,
10311        // otherwise the watchdog may be prevented from resetting the system.
10312
10313        final String dropboxTag = processClass(process) + "_" + eventType;
10314        final DropBoxManager dbox = (DropBoxManager)
10315                mContext.getSystemService(Context.DROPBOX_SERVICE);
10316
10317        // Exit early if the dropbox isn't configured to accept this report type.
10318        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10319
10320        final StringBuilder sb = new StringBuilder(1024);
10321        appendDropBoxProcessHeaders(process, processName, sb);
10322        if (activity != null) {
10323            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10324        }
10325        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10326            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10327        }
10328        if (parent != null && parent != activity) {
10329            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10330        }
10331        if (subject != null) {
10332            sb.append("Subject: ").append(subject).append("\n");
10333        }
10334        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10335        if (Debug.isDebuggerConnected()) {
10336            sb.append("Debugger: Connected\n");
10337        }
10338        sb.append("\n");
10339
10340        // Do the rest in a worker thread to avoid blocking the caller on I/O
10341        // (After this point, we shouldn't access AMS internal data structures.)
10342        Thread worker = new Thread("Error dump: " + dropboxTag) {
10343            @Override
10344            public void run() {
10345                if (report != null) {
10346                    sb.append(report);
10347                }
10348                if (logFile != null) {
10349                    try {
10350                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10351                                    "\n\n[[TRUNCATED]]"));
10352                    } catch (IOException e) {
10353                        Slog.e(TAG, "Error reading " + logFile, e);
10354                    }
10355                }
10356                if (crashInfo != null && crashInfo.stackTrace != null) {
10357                    sb.append(crashInfo.stackTrace);
10358                }
10359
10360                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10361                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10362                if (lines > 0) {
10363                    sb.append("\n");
10364
10365                    // Merge several logcat streams, and take the last N lines
10366                    InputStreamReader input = null;
10367                    try {
10368                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10369                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10370                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10371
10372                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10373                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10374                        input = new InputStreamReader(logcat.getInputStream());
10375
10376                        int num;
10377                        char[] buf = new char[8192];
10378                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10379                    } catch (IOException e) {
10380                        Slog.e(TAG, "Error running logcat", e);
10381                    } finally {
10382                        if (input != null) try { input.close(); } catch (IOException e) {}
10383                    }
10384                }
10385
10386                dbox.addText(dropboxTag, sb.toString());
10387            }
10388        };
10389
10390        if (process == null) {
10391            // If process is null, we are being called from some internal code
10392            // and may be about to die -- run this synchronously.
10393            worker.run();
10394        } else {
10395            worker.start();
10396        }
10397    }
10398
10399    /**
10400     * Bring up the "unexpected error" dialog box for a crashing app.
10401     * Deal with edge cases (intercepts from instrumented applications,
10402     * ActivityController, error intent receivers, that sort of thing).
10403     * @param r the application crashing
10404     * @param crashInfo describing the failure
10405     */
10406    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10407        long timeMillis = System.currentTimeMillis();
10408        String shortMsg = crashInfo.exceptionClassName;
10409        String longMsg = crashInfo.exceptionMessage;
10410        String stackTrace = crashInfo.stackTrace;
10411        if (shortMsg != null && longMsg != null) {
10412            longMsg = shortMsg + ": " + longMsg;
10413        } else if (shortMsg != null) {
10414            longMsg = shortMsg;
10415        }
10416
10417        AppErrorResult result = new AppErrorResult();
10418        synchronized (this) {
10419            if (mController != null) {
10420                try {
10421                    String name = r != null ? r.processName : null;
10422                    int pid = r != null ? r.pid : Binder.getCallingPid();
10423                    if (!mController.appCrashed(name, pid,
10424                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10425                        Slog.w(TAG, "Force-killing crashed app " + name
10426                                + " at watcher's request");
10427                        Process.killProcess(pid);
10428                        return;
10429                    }
10430                } catch (RemoteException e) {
10431                    mController = null;
10432                    Watchdog.getInstance().setActivityController(null);
10433                }
10434            }
10435
10436            final long origId = Binder.clearCallingIdentity();
10437
10438            // If this process is running instrumentation, finish it.
10439            if (r != null && r.instrumentationClass != null) {
10440                Slog.w(TAG, "Error in app " + r.processName
10441                      + " running instrumentation " + r.instrumentationClass + ":");
10442                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10443                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10444                Bundle info = new Bundle();
10445                info.putString("shortMsg", shortMsg);
10446                info.putString("longMsg", longMsg);
10447                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10448                Binder.restoreCallingIdentity(origId);
10449                return;
10450            }
10451
10452            // If we can't identify the process or it's already exceeded its crash quota,
10453            // quit right away without showing a crash dialog.
10454            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10455                Binder.restoreCallingIdentity(origId);
10456                return;
10457            }
10458
10459            Message msg = Message.obtain();
10460            msg.what = SHOW_ERROR_MSG;
10461            HashMap data = new HashMap();
10462            data.put("result", result);
10463            data.put("app", r);
10464            msg.obj = data;
10465            mHandler.sendMessage(msg);
10466
10467            Binder.restoreCallingIdentity(origId);
10468        }
10469
10470        int res = result.get();
10471
10472        Intent appErrorIntent = null;
10473        synchronized (this) {
10474            if (r != null && !r.isolated) {
10475                // XXX Can't keep track of crash time for isolated processes,
10476                // since they don't have a persistent identity.
10477                mProcessCrashTimes.put(r.info.processName, r.uid,
10478                        SystemClock.uptimeMillis());
10479            }
10480            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10481                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10482            }
10483        }
10484
10485        if (appErrorIntent != null) {
10486            try {
10487                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10488            } catch (ActivityNotFoundException e) {
10489                Slog.w(TAG, "bug report receiver dissappeared", e);
10490            }
10491        }
10492    }
10493
10494    Intent createAppErrorIntentLocked(ProcessRecord r,
10495            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10496        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10497        if (report == null) {
10498            return null;
10499        }
10500        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10501        result.setComponent(r.errorReportReceiver);
10502        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10503        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10504        return result;
10505    }
10506
10507    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10508            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10509        if (r.errorReportReceiver == null) {
10510            return null;
10511        }
10512
10513        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10514            return null;
10515        }
10516
10517        ApplicationErrorReport report = new ApplicationErrorReport();
10518        report.packageName = r.info.packageName;
10519        report.installerPackageName = r.errorReportReceiver.getPackageName();
10520        report.processName = r.processName;
10521        report.time = timeMillis;
10522        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10523
10524        if (r.crashing || r.forceCrashReport) {
10525            report.type = ApplicationErrorReport.TYPE_CRASH;
10526            report.crashInfo = crashInfo;
10527        } else if (r.notResponding) {
10528            report.type = ApplicationErrorReport.TYPE_ANR;
10529            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10530
10531            report.anrInfo.activity = r.notRespondingReport.tag;
10532            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10533            report.anrInfo.info = r.notRespondingReport.longMsg;
10534        }
10535
10536        return report;
10537    }
10538
10539    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10540        enforceNotIsolatedCaller("getProcessesInErrorState");
10541        // assume our apps are happy - lazy create the list
10542        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10543
10544        final boolean allUsers = ActivityManager.checkUidPermission(
10545                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10546                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10547        int userId = UserHandle.getUserId(Binder.getCallingUid());
10548
10549        synchronized (this) {
10550
10551            // iterate across all processes
10552            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10553                ProcessRecord app = mLruProcesses.get(i);
10554                if (!allUsers && app.userId != userId) {
10555                    continue;
10556                }
10557                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10558                    // This one's in trouble, so we'll generate a report for it
10559                    // crashes are higher priority (in case there's a crash *and* an anr)
10560                    ActivityManager.ProcessErrorStateInfo report = null;
10561                    if (app.crashing) {
10562                        report = app.crashingReport;
10563                    } else if (app.notResponding) {
10564                        report = app.notRespondingReport;
10565                    }
10566
10567                    if (report != null) {
10568                        if (errList == null) {
10569                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10570                        }
10571                        errList.add(report);
10572                    } else {
10573                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10574                                " crashing = " + app.crashing +
10575                                " notResponding = " + app.notResponding);
10576                    }
10577                }
10578            }
10579        }
10580
10581        return errList;
10582    }
10583
10584    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10585        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10586            if (currApp != null) {
10587                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10588            }
10589            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10590        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10591            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10592        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10593            if (currApp != null) {
10594                currApp.lru = 0;
10595            }
10596            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10597        } else if (adj >= ProcessList.SERVICE_ADJ) {
10598            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10599        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10600            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10601        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10602            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10603        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10604            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10605        } else {
10606            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10607        }
10608    }
10609
10610    private void fillInProcMemInfo(ProcessRecord app,
10611            ActivityManager.RunningAppProcessInfo outInfo) {
10612        outInfo.pid = app.pid;
10613        outInfo.uid = app.info.uid;
10614        if (mHeavyWeightProcess == app) {
10615            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10616        }
10617        if (app.persistent) {
10618            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10619        }
10620        if (app.activities.size() > 0) {
10621            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10622        }
10623        outInfo.lastTrimLevel = app.trimMemoryLevel;
10624        int adj = app.curAdj;
10625        outInfo.importance = oomAdjToImportance(adj, outInfo);
10626        outInfo.importanceReasonCode = app.adjTypeCode;
10627        outInfo.processState = app.curProcState;
10628    }
10629
10630    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10631        enforceNotIsolatedCaller("getRunningAppProcesses");
10632        // Lazy instantiation of list
10633        List<ActivityManager.RunningAppProcessInfo> runList = null;
10634        final boolean allUsers = ActivityManager.checkUidPermission(
10635                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10636                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10637        int userId = UserHandle.getUserId(Binder.getCallingUid());
10638        synchronized (this) {
10639            // Iterate across all processes
10640            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10641                ProcessRecord app = mLruProcesses.get(i);
10642                if (!allUsers && app.userId != userId) {
10643                    continue;
10644                }
10645                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10646                    // Generate process state info for running application
10647                    ActivityManager.RunningAppProcessInfo currApp =
10648                        new ActivityManager.RunningAppProcessInfo(app.processName,
10649                                app.pid, app.getPackageList());
10650                    fillInProcMemInfo(app, currApp);
10651                    if (app.adjSource instanceof ProcessRecord) {
10652                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10653                        currApp.importanceReasonImportance = oomAdjToImportance(
10654                                app.adjSourceOom, null);
10655                    } else if (app.adjSource instanceof ActivityRecord) {
10656                        ActivityRecord r = (ActivityRecord)app.adjSource;
10657                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10658                    }
10659                    if (app.adjTarget instanceof ComponentName) {
10660                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10661                    }
10662                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10663                    //        + " lru=" + currApp.lru);
10664                    if (runList == null) {
10665                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10666                    }
10667                    runList.add(currApp);
10668                }
10669            }
10670        }
10671        return runList;
10672    }
10673
10674    public List<ApplicationInfo> getRunningExternalApplications() {
10675        enforceNotIsolatedCaller("getRunningExternalApplications");
10676        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10677        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10678        if (runningApps != null && runningApps.size() > 0) {
10679            Set<String> extList = new HashSet<String>();
10680            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10681                if (app.pkgList != null) {
10682                    for (String pkg : app.pkgList) {
10683                        extList.add(pkg);
10684                    }
10685                }
10686            }
10687            IPackageManager pm = AppGlobals.getPackageManager();
10688            for (String pkg : extList) {
10689                try {
10690                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10691                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10692                        retList.add(info);
10693                    }
10694                } catch (RemoteException e) {
10695                }
10696            }
10697        }
10698        return retList;
10699    }
10700
10701    @Override
10702    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10703        enforceNotIsolatedCaller("getMyMemoryState");
10704        synchronized (this) {
10705            ProcessRecord proc;
10706            synchronized (mPidsSelfLocked) {
10707                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10708            }
10709            fillInProcMemInfo(proc, outInfo);
10710        }
10711    }
10712
10713    @Override
10714    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10715        if (checkCallingPermission(android.Manifest.permission.DUMP)
10716                != PackageManager.PERMISSION_GRANTED) {
10717            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10718                    + Binder.getCallingPid()
10719                    + ", uid=" + Binder.getCallingUid()
10720                    + " without permission "
10721                    + android.Manifest.permission.DUMP);
10722            return;
10723        }
10724
10725        boolean dumpAll = false;
10726        boolean dumpClient = false;
10727        String dumpPackage = null;
10728
10729        int opti = 0;
10730        while (opti < args.length) {
10731            String opt = args[opti];
10732            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10733                break;
10734            }
10735            opti++;
10736            if ("-a".equals(opt)) {
10737                dumpAll = true;
10738            } else if ("-c".equals(opt)) {
10739                dumpClient = true;
10740            } else if ("-h".equals(opt)) {
10741                pw.println("Activity manager dump options:");
10742                pw.println("  [-a] [-c] [-h] [cmd] ...");
10743                pw.println("  cmd may be one of:");
10744                pw.println("    a[ctivities]: activity stack state");
10745                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10746                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10747                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10748                pw.println("    o[om]: out of memory management");
10749                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10750                pw.println("    provider [COMP_SPEC]: provider client-side state");
10751                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10752                pw.println("    service [COMP_SPEC]: service client-side state");
10753                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10754                pw.println("    all: dump all activities");
10755                pw.println("    top: dump the top activity");
10756                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10757                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10758                pw.println("    a partial substring in a component name, a");
10759                pw.println("    hex object identifier.");
10760                pw.println("  -a: include all available server state.");
10761                pw.println("  -c: include client state.");
10762                return;
10763            } else {
10764                pw.println("Unknown argument: " + opt + "; use -h for help");
10765            }
10766        }
10767
10768        long origId = Binder.clearCallingIdentity();
10769        boolean more = false;
10770        // Is the caller requesting to dump a particular piece of data?
10771        if (opti < args.length) {
10772            String cmd = args[opti];
10773            opti++;
10774            if ("activities".equals(cmd) || "a".equals(cmd)) {
10775                synchronized (this) {
10776                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10777                }
10778            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10779                String[] newArgs;
10780                String name;
10781                if (opti >= args.length) {
10782                    name = null;
10783                    newArgs = EMPTY_STRING_ARRAY;
10784                } else {
10785                    name = args[opti];
10786                    opti++;
10787                    newArgs = new String[args.length - opti];
10788                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10789                            args.length - opti);
10790                }
10791                synchronized (this) {
10792                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10793                }
10794            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10795                String[] newArgs;
10796                String name;
10797                if (opti >= args.length) {
10798                    name = null;
10799                    newArgs = EMPTY_STRING_ARRAY;
10800                } else {
10801                    name = args[opti];
10802                    opti++;
10803                    newArgs = new String[args.length - opti];
10804                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10805                            args.length - opti);
10806                }
10807                synchronized (this) {
10808                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10809                }
10810            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10811                String[] newArgs;
10812                String name;
10813                if (opti >= args.length) {
10814                    name = null;
10815                    newArgs = EMPTY_STRING_ARRAY;
10816                } else {
10817                    name = args[opti];
10818                    opti++;
10819                    newArgs = new String[args.length - opti];
10820                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10821                            args.length - opti);
10822                }
10823                synchronized (this) {
10824                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10825                }
10826            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10827                synchronized (this) {
10828                    dumpOomLocked(fd, pw, args, opti, true);
10829                }
10830            } else if ("provider".equals(cmd)) {
10831                String[] newArgs;
10832                String name;
10833                if (opti >= args.length) {
10834                    name = null;
10835                    newArgs = EMPTY_STRING_ARRAY;
10836                } else {
10837                    name = args[opti];
10838                    opti++;
10839                    newArgs = new String[args.length - opti];
10840                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10841                }
10842                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10843                    pw.println("No providers match: " + name);
10844                    pw.println("Use -h for help.");
10845                }
10846            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10847                synchronized (this) {
10848                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10849                }
10850            } else if ("service".equals(cmd)) {
10851                String[] newArgs;
10852                String name;
10853                if (opti >= args.length) {
10854                    name = null;
10855                    newArgs = EMPTY_STRING_ARRAY;
10856                } else {
10857                    name = args[opti];
10858                    opti++;
10859                    newArgs = new String[args.length - opti];
10860                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10861                            args.length - opti);
10862                }
10863                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10864                    pw.println("No services match: " + name);
10865                    pw.println("Use -h for help.");
10866                }
10867            } else if ("package".equals(cmd)) {
10868                String[] newArgs;
10869                if (opti >= args.length) {
10870                    pw.println("package: no package name specified");
10871                    pw.println("Use -h for help.");
10872                } else {
10873                    dumpPackage = args[opti];
10874                    opti++;
10875                    newArgs = new String[args.length - opti];
10876                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10877                            args.length - opti);
10878                    args = newArgs;
10879                    opti = 0;
10880                    more = true;
10881                }
10882            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10883                synchronized (this) {
10884                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10885                }
10886            } else {
10887                // Dumping a single activity?
10888                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10889                    pw.println("Bad activity command, or no activities match: " + cmd);
10890                    pw.println("Use -h for help.");
10891                }
10892            }
10893            if (!more) {
10894                Binder.restoreCallingIdentity(origId);
10895                return;
10896            }
10897        }
10898
10899        // No piece of data specified, dump everything.
10900        synchronized (this) {
10901            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10902            pw.println();
10903            if (dumpAll) {
10904                pw.println("-------------------------------------------------------------------------------");
10905            }
10906            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10907            pw.println();
10908            if (dumpAll) {
10909                pw.println("-------------------------------------------------------------------------------");
10910            }
10911            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10912            pw.println();
10913            if (dumpAll) {
10914                pw.println("-------------------------------------------------------------------------------");
10915            }
10916            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10917            pw.println();
10918            if (dumpAll) {
10919                pw.println("-------------------------------------------------------------------------------");
10920            }
10921            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10922            pw.println();
10923            if (dumpAll) {
10924                pw.println("-------------------------------------------------------------------------------");
10925            }
10926            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10927        }
10928        Binder.restoreCallingIdentity(origId);
10929    }
10930
10931    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10932            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10933        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10934
10935        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10936                dumpPackage);
10937        boolean needSep = printedAnything;
10938
10939        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10940                dumpPackage, needSep, "  mFocusedActivity: ");
10941        if (printed) {
10942            printedAnything = true;
10943            needSep = false;
10944        }
10945
10946        if (dumpPackage == null) {
10947            if (needSep) {
10948                pw.println();
10949            }
10950            needSep = true;
10951            printedAnything = true;
10952            mStackSupervisor.dump(pw, "  ");
10953        }
10954
10955        if (mRecentTasks.size() > 0) {
10956            boolean printedHeader = false;
10957
10958            final int N = mRecentTasks.size();
10959            for (int i=0; i<N; i++) {
10960                TaskRecord tr = mRecentTasks.get(i);
10961                if (dumpPackage != null) {
10962                    if (tr.realActivity == null ||
10963                            !dumpPackage.equals(tr.realActivity)) {
10964                        continue;
10965                    }
10966                }
10967                if (!printedHeader) {
10968                    if (needSep) {
10969                        pw.println();
10970                    }
10971                    pw.println("  Recent tasks:");
10972                    printedHeader = true;
10973                    printedAnything = true;
10974                }
10975                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10976                        pw.println(tr);
10977                if (dumpAll) {
10978                    mRecentTasks.get(i).dump(pw, "    ");
10979                }
10980            }
10981        }
10982
10983        if (!printedAnything) {
10984            pw.println("  (nothing)");
10985        }
10986    }
10987
10988    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10989            int opti, boolean dumpAll, String dumpPackage) {
10990        boolean needSep = false;
10991        boolean printedAnything = false;
10992        int numPers = 0;
10993
10994        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10995
10996        if (dumpAll) {
10997            final int NP = mProcessNames.getMap().size();
10998            for (int ip=0; ip<NP; ip++) {
10999                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11000                final int NA = procs.size();
11001                for (int ia=0; ia<NA; ia++) {
11002                    ProcessRecord r = procs.valueAt(ia);
11003                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11004                        continue;
11005                    }
11006                    if (!needSep) {
11007                        pw.println("  All known processes:");
11008                        needSep = true;
11009                        printedAnything = true;
11010                    }
11011                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11012                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11013                        pw.print(" "); pw.println(r);
11014                    r.dump(pw, "    ");
11015                    if (r.persistent) {
11016                        numPers++;
11017                    }
11018                }
11019            }
11020        }
11021
11022        if (mIsolatedProcesses.size() > 0) {
11023            boolean printed = false;
11024            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11025                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11026                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11027                    continue;
11028                }
11029                if (!printed) {
11030                    if (needSep) {
11031                        pw.println();
11032                    }
11033                    pw.println("  Isolated process list (sorted by uid):");
11034                    printedAnything = true;
11035                    printed = true;
11036                    needSep = true;
11037                }
11038                pw.println(String.format("%sIsolated #%2d: %s",
11039                        "    ", i, r.toString()));
11040            }
11041        }
11042
11043        if (mLruProcesses.size() > 0) {
11044            if (needSep) {
11045                pw.println();
11046            }
11047            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11048                    pw.print(" total, non-act at ");
11049                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11050                    pw.print(", non-svc at ");
11051                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11052                    pw.println("):");
11053            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11054            needSep = true;
11055            printedAnything = true;
11056        }
11057
11058        if (dumpAll || dumpPackage != null) {
11059            synchronized (mPidsSelfLocked) {
11060                boolean printed = false;
11061                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11062                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11063                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11064                        continue;
11065                    }
11066                    if (!printed) {
11067                        if (needSep) pw.println();
11068                        needSep = true;
11069                        pw.println("  PID mappings:");
11070                        printed = true;
11071                        printedAnything = true;
11072                    }
11073                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11074                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11075                }
11076            }
11077        }
11078
11079        if (mForegroundProcesses.size() > 0) {
11080            synchronized (mPidsSelfLocked) {
11081                boolean printed = false;
11082                for (int i=0; i<mForegroundProcesses.size(); i++) {
11083                    ProcessRecord r = mPidsSelfLocked.get(
11084                            mForegroundProcesses.valueAt(i).pid);
11085                    if (dumpPackage != null && (r == null
11086                            || !r.pkgList.containsKey(dumpPackage))) {
11087                        continue;
11088                    }
11089                    if (!printed) {
11090                        if (needSep) pw.println();
11091                        needSep = true;
11092                        pw.println("  Foreground Processes:");
11093                        printed = true;
11094                        printedAnything = true;
11095                    }
11096                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11097                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11098                }
11099            }
11100        }
11101
11102        if (mPersistentStartingProcesses.size() > 0) {
11103            if (needSep) pw.println();
11104            needSep = true;
11105            printedAnything = true;
11106            pw.println("  Persisent processes that are starting:");
11107            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11108                    "Starting Norm", "Restarting PERS", dumpPackage);
11109        }
11110
11111        if (mRemovedProcesses.size() > 0) {
11112            if (needSep) pw.println();
11113            needSep = true;
11114            printedAnything = true;
11115            pw.println("  Processes that are being removed:");
11116            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11117                    "Removed Norm", "Removed PERS", dumpPackage);
11118        }
11119
11120        if (mProcessesOnHold.size() > 0) {
11121            if (needSep) pw.println();
11122            needSep = true;
11123            printedAnything = true;
11124            pw.println("  Processes that are on old until the system is ready:");
11125            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11126                    "OnHold Norm", "OnHold PERS", dumpPackage);
11127        }
11128
11129        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11130
11131        if (mProcessCrashTimes.getMap().size() > 0) {
11132            boolean printed = false;
11133            long now = SystemClock.uptimeMillis();
11134            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11135            final int NP = pmap.size();
11136            for (int ip=0; ip<NP; ip++) {
11137                String pname = pmap.keyAt(ip);
11138                SparseArray<Long> uids = pmap.valueAt(ip);
11139                final int N = uids.size();
11140                for (int i=0; i<N; i++) {
11141                    int puid = uids.keyAt(i);
11142                    ProcessRecord r = mProcessNames.get(pname, puid);
11143                    if (dumpPackage != null && (r == null
11144                            || !r.pkgList.containsKey(dumpPackage))) {
11145                        continue;
11146                    }
11147                    if (!printed) {
11148                        if (needSep) pw.println();
11149                        needSep = true;
11150                        pw.println("  Time since processes crashed:");
11151                        printed = true;
11152                        printedAnything = true;
11153                    }
11154                    pw.print("    Process "); pw.print(pname);
11155                            pw.print(" uid "); pw.print(puid);
11156                            pw.print(": last crashed ");
11157                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11158                            pw.println(" ago");
11159                }
11160            }
11161        }
11162
11163        if (mBadProcesses.getMap().size() > 0) {
11164            boolean printed = false;
11165            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11166            final int NP = pmap.size();
11167            for (int ip=0; ip<NP; ip++) {
11168                String pname = pmap.keyAt(ip);
11169                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11170                final int N = uids.size();
11171                for (int i=0; i<N; i++) {
11172                    int puid = uids.keyAt(i);
11173                    ProcessRecord r = mProcessNames.get(pname, puid);
11174                    if (dumpPackage != null && (r == null
11175                            || !r.pkgList.containsKey(dumpPackage))) {
11176                        continue;
11177                    }
11178                    if (!printed) {
11179                        if (needSep) pw.println();
11180                        needSep = true;
11181                        pw.println("  Bad processes:");
11182                        printedAnything = true;
11183                    }
11184                    BadProcessInfo info = uids.valueAt(i);
11185                    pw.print("    Bad process "); pw.print(pname);
11186                            pw.print(" uid "); pw.print(puid);
11187                            pw.print(": crashed at time "); pw.println(info.time);
11188                    if (info.shortMsg != null) {
11189                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11190                    }
11191                    if (info.longMsg != null) {
11192                        pw.print("      Long msg: "); pw.println(info.longMsg);
11193                    }
11194                    if (info.stack != null) {
11195                        pw.println("      Stack:");
11196                        int lastPos = 0;
11197                        for (int pos=0; pos<info.stack.length(); pos++) {
11198                            if (info.stack.charAt(pos) == '\n') {
11199                                pw.print("        ");
11200                                pw.write(info.stack, lastPos, pos-lastPos);
11201                                pw.println();
11202                                lastPos = pos+1;
11203                            }
11204                        }
11205                        if (lastPos < info.stack.length()) {
11206                            pw.print("        ");
11207                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11208                            pw.println();
11209                        }
11210                    }
11211                }
11212            }
11213        }
11214
11215        if (dumpPackage == null) {
11216            pw.println();
11217            needSep = false;
11218            pw.println("  mStartedUsers:");
11219            for (int i=0; i<mStartedUsers.size(); i++) {
11220                UserStartedState uss = mStartedUsers.valueAt(i);
11221                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11222                        pw.print(": "); uss.dump("", pw);
11223            }
11224            pw.print("  mStartedUserArray: [");
11225            for (int i=0; i<mStartedUserArray.length; i++) {
11226                if (i > 0) pw.print(", ");
11227                pw.print(mStartedUserArray[i]);
11228            }
11229            pw.println("]");
11230            pw.print("  mUserLru: [");
11231            for (int i=0; i<mUserLru.size(); i++) {
11232                if (i > 0) pw.print(", ");
11233                pw.print(mUserLru.get(i));
11234            }
11235            pw.println("]");
11236            if (dumpAll) {
11237                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11238            }
11239        }
11240        if (mHomeProcess != null && (dumpPackage == null
11241                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11242            if (needSep) {
11243                pw.println();
11244                needSep = false;
11245            }
11246            pw.println("  mHomeProcess: " + mHomeProcess);
11247        }
11248        if (mPreviousProcess != null && (dumpPackage == null
11249                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11250            if (needSep) {
11251                pw.println();
11252                needSep = false;
11253            }
11254            pw.println("  mPreviousProcess: " + mPreviousProcess);
11255        }
11256        if (dumpAll) {
11257            StringBuilder sb = new StringBuilder(128);
11258            sb.append("  mPreviousProcessVisibleTime: ");
11259            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11260            pw.println(sb);
11261        }
11262        if (mHeavyWeightProcess != null && (dumpPackage == null
11263                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11264            if (needSep) {
11265                pw.println();
11266                needSep = false;
11267            }
11268            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11269        }
11270        if (dumpPackage == null) {
11271            pw.println("  mConfiguration: " + mConfiguration);
11272        }
11273        if (dumpAll) {
11274            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11275            if (mCompatModePackages.getPackages().size() > 0) {
11276                boolean printed = false;
11277                for (Map.Entry<String, Integer> entry
11278                        : mCompatModePackages.getPackages().entrySet()) {
11279                    String pkg = entry.getKey();
11280                    int mode = entry.getValue();
11281                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11282                        continue;
11283                    }
11284                    if (!printed) {
11285                        pw.println("  mScreenCompatPackages:");
11286                        printed = true;
11287                    }
11288                    pw.print("    "); pw.print(pkg); pw.print(": ");
11289                            pw.print(mode); pw.println();
11290                }
11291            }
11292        }
11293        if (dumpPackage == null) {
11294            if (mSleeping || mWentToSleep || mLockScreenShown) {
11295                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11296                        + " mLockScreenShown " + mLockScreenShown);
11297            }
11298            if (mShuttingDown || mRunningVoice) {
11299                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11300            }
11301        }
11302        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11303                || mOrigWaitForDebugger) {
11304            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11305                    || dumpPackage.equals(mOrigDebugApp)) {
11306                if (needSep) {
11307                    pw.println();
11308                    needSep = false;
11309                }
11310                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11311                        + " mDebugTransient=" + mDebugTransient
11312                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11313            }
11314        }
11315        if (mOpenGlTraceApp != null) {
11316            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11317                if (needSep) {
11318                    pw.println();
11319                    needSep = false;
11320                }
11321                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11322            }
11323        }
11324        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11325                || mProfileFd != null) {
11326            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11327                if (needSep) {
11328                    pw.println();
11329                    needSep = false;
11330                }
11331                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11332                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11333                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11334                        + mAutoStopProfiler);
11335            }
11336        }
11337        if (dumpPackage == null) {
11338            if (mAlwaysFinishActivities || mController != null) {
11339                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11340                        + " mController=" + mController);
11341            }
11342            if (dumpAll) {
11343                pw.println("  Total persistent processes: " + numPers);
11344                pw.println("  mProcessesReady=" + mProcessesReady
11345                        + " mSystemReady=" + mSystemReady);
11346                pw.println("  mBooting=" + mBooting
11347                        + " mBooted=" + mBooted
11348                        + " mFactoryTest=" + mFactoryTest);
11349                pw.print("  mLastPowerCheckRealtime=");
11350                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11351                        pw.println("");
11352                pw.print("  mLastPowerCheckUptime=");
11353                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11354                        pw.println("");
11355                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11356                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11357                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11358                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11359                        + " (" + mLruProcesses.size() + " total)"
11360                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11361                        + " mNumServiceProcs=" + mNumServiceProcs
11362                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11363                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11364                        + " mLastMemoryLevel" + mLastMemoryLevel
11365                        + " mLastNumProcesses" + mLastNumProcesses);
11366                long now = SystemClock.uptimeMillis();
11367                pw.print("  mLastIdleTime=");
11368                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11369                        pw.print(" mLowRamSinceLastIdle=");
11370                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11371                        pw.println();
11372            }
11373        }
11374
11375        if (!printedAnything) {
11376            pw.println("  (nothing)");
11377        }
11378    }
11379
11380    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11381            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11382        if (mProcessesToGc.size() > 0) {
11383            boolean printed = false;
11384            long now = SystemClock.uptimeMillis();
11385            for (int i=0; i<mProcessesToGc.size(); i++) {
11386                ProcessRecord proc = mProcessesToGc.get(i);
11387                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11388                    continue;
11389                }
11390                if (!printed) {
11391                    if (needSep) pw.println();
11392                    needSep = true;
11393                    pw.println("  Processes that are waiting to GC:");
11394                    printed = true;
11395                }
11396                pw.print("    Process "); pw.println(proc);
11397                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11398                        pw.print(", last gced=");
11399                        pw.print(now-proc.lastRequestedGc);
11400                        pw.print(" ms ago, last lowMem=");
11401                        pw.print(now-proc.lastLowMemory);
11402                        pw.println(" ms ago");
11403
11404            }
11405        }
11406        return needSep;
11407    }
11408
11409    void printOomLevel(PrintWriter pw, String name, int adj) {
11410        pw.print("    ");
11411        if (adj >= 0) {
11412            pw.print(' ');
11413            if (adj < 10) pw.print(' ');
11414        } else {
11415            if (adj > -10) pw.print(' ');
11416        }
11417        pw.print(adj);
11418        pw.print(": ");
11419        pw.print(name);
11420        pw.print(" (");
11421        pw.print(mProcessList.getMemLevel(adj)/1024);
11422        pw.println(" kB)");
11423    }
11424
11425    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11426            int opti, boolean dumpAll) {
11427        boolean needSep = false;
11428
11429        if (mLruProcesses.size() > 0) {
11430            if (needSep) pw.println();
11431            needSep = true;
11432            pw.println("  OOM levels:");
11433            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11434            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11435            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11436            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11437            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11438            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11439            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11440            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11441            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11442            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11443            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11444            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11445            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11446
11447            if (needSep) pw.println();
11448            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11449                    pw.print(" total, non-act at ");
11450                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11451                    pw.print(", non-svc at ");
11452                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11453                    pw.println("):");
11454            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11455            needSep = true;
11456        }
11457
11458        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11459
11460        pw.println();
11461        pw.println("  mHomeProcess: " + mHomeProcess);
11462        pw.println("  mPreviousProcess: " + mPreviousProcess);
11463        if (mHeavyWeightProcess != null) {
11464            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11465        }
11466
11467        return true;
11468    }
11469
11470    /**
11471     * There are three ways to call this:
11472     *  - no provider specified: dump all the providers
11473     *  - a flattened component name that matched an existing provider was specified as the
11474     *    first arg: dump that one provider
11475     *  - the first arg isn't the flattened component name of an existing provider:
11476     *    dump all providers whose component contains the first arg as a substring
11477     */
11478    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11479            int opti, boolean dumpAll) {
11480        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11481    }
11482
11483    static class ItemMatcher {
11484        ArrayList<ComponentName> components;
11485        ArrayList<String> strings;
11486        ArrayList<Integer> objects;
11487        boolean all;
11488
11489        ItemMatcher() {
11490            all = true;
11491        }
11492
11493        void build(String name) {
11494            ComponentName componentName = ComponentName.unflattenFromString(name);
11495            if (componentName != null) {
11496                if (components == null) {
11497                    components = new ArrayList<ComponentName>();
11498                }
11499                components.add(componentName);
11500                all = false;
11501            } else {
11502                int objectId = 0;
11503                // Not a '/' separated full component name; maybe an object ID?
11504                try {
11505                    objectId = Integer.parseInt(name, 16);
11506                    if (objects == null) {
11507                        objects = new ArrayList<Integer>();
11508                    }
11509                    objects.add(objectId);
11510                    all = false;
11511                } catch (RuntimeException e) {
11512                    // Not an integer; just do string match.
11513                    if (strings == null) {
11514                        strings = new ArrayList<String>();
11515                    }
11516                    strings.add(name);
11517                    all = false;
11518                }
11519            }
11520        }
11521
11522        int build(String[] args, int opti) {
11523            for (; opti<args.length; opti++) {
11524                String name = args[opti];
11525                if ("--".equals(name)) {
11526                    return opti+1;
11527                }
11528                build(name);
11529            }
11530            return opti;
11531        }
11532
11533        boolean match(Object object, ComponentName comp) {
11534            if (all) {
11535                return true;
11536            }
11537            if (components != null) {
11538                for (int i=0; i<components.size(); i++) {
11539                    if (components.get(i).equals(comp)) {
11540                        return true;
11541                    }
11542                }
11543            }
11544            if (objects != null) {
11545                for (int i=0; i<objects.size(); i++) {
11546                    if (System.identityHashCode(object) == objects.get(i)) {
11547                        return true;
11548                    }
11549                }
11550            }
11551            if (strings != null) {
11552                String flat = comp.flattenToString();
11553                for (int i=0; i<strings.size(); i++) {
11554                    if (flat.contains(strings.get(i))) {
11555                        return true;
11556                    }
11557                }
11558            }
11559            return false;
11560        }
11561    }
11562
11563    /**
11564     * There are three things that cmd can be:
11565     *  - a flattened component name that matches an existing activity
11566     *  - the cmd arg isn't the flattened component name of an existing activity:
11567     *    dump all activity whose component contains the cmd as a substring
11568     *  - A hex number of the ActivityRecord object instance.
11569     */
11570    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11571            int opti, boolean dumpAll) {
11572        ArrayList<ActivityRecord> activities;
11573
11574        synchronized (this) {
11575            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11576        }
11577
11578        if (activities.size() <= 0) {
11579            return false;
11580        }
11581
11582        String[] newArgs = new String[args.length - opti];
11583        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11584
11585        TaskRecord lastTask = null;
11586        boolean needSep = false;
11587        for (int i=activities.size()-1; i>=0; i--) {
11588            ActivityRecord r = activities.get(i);
11589            if (needSep) {
11590                pw.println();
11591            }
11592            needSep = true;
11593            synchronized (this) {
11594                if (lastTask != r.task) {
11595                    lastTask = r.task;
11596                    pw.print("TASK "); pw.print(lastTask.affinity);
11597                            pw.print(" id="); pw.println(lastTask.taskId);
11598                    if (dumpAll) {
11599                        lastTask.dump(pw, "  ");
11600                    }
11601                }
11602            }
11603            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11604        }
11605        return true;
11606    }
11607
11608    /**
11609     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11610     * there is a thread associated with the activity.
11611     */
11612    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11613            final ActivityRecord r, String[] args, boolean dumpAll) {
11614        String innerPrefix = prefix + "  ";
11615        synchronized (this) {
11616            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11617                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11618                    pw.print(" pid=");
11619                    if (r.app != null) pw.println(r.app.pid);
11620                    else pw.println("(not running)");
11621            if (dumpAll) {
11622                r.dump(pw, innerPrefix);
11623            }
11624        }
11625        if (r.app != null && r.app.thread != null) {
11626            // flush anything that is already in the PrintWriter since the thread is going
11627            // to write to the file descriptor directly
11628            pw.flush();
11629            try {
11630                TransferPipe tp = new TransferPipe();
11631                try {
11632                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11633                            r.appToken, innerPrefix, args);
11634                    tp.go(fd);
11635                } finally {
11636                    tp.kill();
11637                }
11638            } catch (IOException e) {
11639                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11640            } catch (RemoteException e) {
11641                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11642            }
11643        }
11644    }
11645
11646    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11647            int opti, boolean dumpAll, String dumpPackage) {
11648        boolean needSep = false;
11649        boolean onlyHistory = false;
11650        boolean printedAnything = false;
11651
11652        if ("history".equals(dumpPackage)) {
11653            if (opti < args.length && "-s".equals(args[opti])) {
11654                dumpAll = false;
11655            }
11656            onlyHistory = true;
11657            dumpPackage = null;
11658        }
11659
11660        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11661        if (!onlyHistory && dumpAll) {
11662            if (mRegisteredReceivers.size() > 0) {
11663                boolean printed = false;
11664                Iterator it = mRegisteredReceivers.values().iterator();
11665                while (it.hasNext()) {
11666                    ReceiverList r = (ReceiverList)it.next();
11667                    if (dumpPackage != null && (r.app == null ||
11668                            !dumpPackage.equals(r.app.info.packageName))) {
11669                        continue;
11670                    }
11671                    if (!printed) {
11672                        pw.println("  Registered Receivers:");
11673                        needSep = true;
11674                        printed = true;
11675                        printedAnything = true;
11676                    }
11677                    pw.print("  * "); pw.println(r);
11678                    r.dump(pw, "    ");
11679                }
11680            }
11681
11682            if (mReceiverResolver.dump(pw, needSep ?
11683                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11684                    "    ", dumpPackage, false)) {
11685                needSep = true;
11686                printedAnything = true;
11687            }
11688        }
11689
11690        for (BroadcastQueue q : mBroadcastQueues) {
11691            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11692            printedAnything |= needSep;
11693        }
11694
11695        needSep = true;
11696
11697        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11698            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11699                if (needSep) {
11700                    pw.println();
11701                }
11702                needSep = true;
11703                printedAnything = true;
11704                pw.print("  Sticky broadcasts for user ");
11705                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11706                StringBuilder sb = new StringBuilder(128);
11707                for (Map.Entry<String, ArrayList<Intent>> ent
11708                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11709                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11710                    if (dumpAll) {
11711                        pw.println(":");
11712                        ArrayList<Intent> intents = ent.getValue();
11713                        final int N = intents.size();
11714                        for (int i=0; i<N; i++) {
11715                            sb.setLength(0);
11716                            sb.append("    Intent: ");
11717                            intents.get(i).toShortString(sb, false, true, false, false);
11718                            pw.println(sb.toString());
11719                            Bundle bundle = intents.get(i).getExtras();
11720                            if (bundle != null) {
11721                                pw.print("      ");
11722                                pw.println(bundle.toString());
11723                            }
11724                        }
11725                    } else {
11726                        pw.println("");
11727                    }
11728                }
11729            }
11730        }
11731
11732        if (!onlyHistory && dumpAll) {
11733            pw.println();
11734            for (BroadcastQueue queue : mBroadcastQueues) {
11735                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11736                        + queue.mBroadcastsScheduled);
11737            }
11738            pw.println("  mHandler:");
11739            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11740            needSep = true;
11741            printedAnything = true;
11742        }
11743
11744        if (!printedAnything) {
11745            pw.println("  (nothing)");
11746        }
11747    }
11748
11749    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11750            int opti, boolean dumpAll, String dumpPackage) {
11751        boolean needSep;
11752        boolean printedAnything = false;
11753
11754        ItemMatcher matcher = new ItemMatcher();
11755        matcher.build(args, opti);
11756
11757        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11758
11759        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11760        printedAnything |= needSep;
11761
11762        if (mLaunchingProviders.size() > 0) {
11763            boolean printed = false;
11764            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11765                ContentProviderRecord r = mLaunchingProviders.get(i);
11766                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11767                    continue;
11768                }
11769                if (!printed) {
11770                    if (needSep) pw.println();
11771                    needSep = true;
11772                    pw.println("  Launching content providers:");
11773                    printed = true;
11774                    printedAnything = true;
11775                }
11776                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11777                        pw.println(r);
11778            }
11779        }
11780
11781        if (mGrantedUriPermissions.size() > 0) {
11782            boolean printed = false;
11783            int dumpUid = -2;
11784            if (dumpPackage != null) {
11785                try {
11786                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11787                } catch (NameNotFoundException e) {
11788                    dumpUid = -1;
11789                }
11790            }
11791            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11792                int uid = mGrantedUriPermissions.keyAt(i);
11793                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11794                    continue;
11795                }
11796                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11797                if (!printed) {
11798                    if (needSep) pw.println();
11799                    needSep = true;
11800                    pw.println("  Granted Uri Permissions:");
11801                    printed = true;
11802                    printedAnything = true;
11803                }
11804                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11805                for (UriPermission perm : perms.values()) {
11806                    pw.print("    "); pw.println(perm);
11807                    if (dumpAll) {
11808                        perm.dump(pw, "      ");
11809                    }
11810                }
11811            }
11812        }
11813
11814        if (!printedAnything) {
11815            pw.println("  (nothing)");
11816        }
11817    }
11818
11819    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11820            int opti, boolean dumpAll, String dumpPackage) {
11821        boolean printed = false;
11822
11823        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11824
11825        if (mIntentSenderRecords.size() > 0) {
11826            Iterator<WeakReference<PendingIntentRecord>> it
11827                    = mIntentSenderRecords.values().iterator();
11828            while (it.hasNext()) {
11829                WeakReference<PendingIntentRecord> ref = it.next();
11830                PendingIntentRecord rec = ref != null ? ref.get(): null;
11831                if (dumpPackage != null && (rec == null
11832                        || !dumpPackage.equals(rec.key.packageName))) {
11833                    continue;
11834                }
11835                printed = true;
11836                if (rec != null) {
11837                    pw.print("  * "); pw.println(rec);
11838                    if (dumpAll) {
11839                        rec.dump(pw, "    ");
11840                    }
11841                } else {
11842                    pw.print("  * "); pw.println(ref);
11843                }
11844            }
11845        }
11846
11847        if (!printed) {
11848            pw.println("  (nothing)");
11849        }
11850    }
11851
11852    private static final int dumpProcessList(PrintWriter pw,
11853            ActivityManagerService service, List list,
11854            String prefix, String normalLabel, String persistentLabel,
11855            String dumpPackage) {
11856        int numPers = 0;
11857        final int N = list.size()-1;
11858        for (int i=N; i>=0; i--) {
11859            ProcessRecord r = (ProcessRecord)list.get(i);
11860            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11861                continue;
11862            }
11863            pw.println(String.format("%s%s #%2d: %s",
11864                    prefix, (r.persistent ? persistentLabel : normalLabel),
11865                    i, r.toString()));
11866            if (r.persistent) {
11867                numPers++;
11868            }
11869        }
11870        return numPers;
11871    }
11872
11873    private static final boolean dumpProcessOomList(PrintWriter pw,
11874            ActivityManagerService service, List<ProcessRecord> origList,
11875            String prefix, String normalLabel, String persistentLabel,
11876            boolean inclDetails, String dumpPackage) {
11877
11878        ArrayList<Pair<ProcessRecord, Integer>> list
11879                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11880        for (int i=0; i<origList.size(); i++) {
11881            ProcessRecord r = origList.get(i);
11882            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11883                continue;
11884            }
11885            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11886        }
11887
11888        if (list.size() <= 0) {
11889            return false;
11890        }
11891
11892        Comparator<Pair<ProcessRecord, Integer>> comparator
11893                = new Comparator<Pair<ProcessRecord, Integer>>() {
11894            @Override
11895            public int compare(Pair<ProcessRecord, Integer> object1,
11896                    Pair<ProcessRecord, Integer> object2) {
11897                if (object1.first.setAdj != object2.first.setAdj) {
11898                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11899                }
11900                if (object1.second.intValue() != object2.second.intValue()) {
11901                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11902                }
11903                return 0;
11904            }
11905        };
11906
11907        Collections.sort(list, comparator);
11908
11909        final long curRealtime = SystemClock.elapsedRealtime();
11910        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11911        final long curUptime = SystemClock.uptimeMillis();
11912        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11913
11914        for (int i=list.size()-1; i>=0; i--) {
11915            ProcessRecord r = list.get(i).first;
11916            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11917            char schedGroup;
11918            switch (r.setSchedGroup) {
11919                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11920                    schedGroup = 'B';
11921                    break;
11922                case Process.THREAD_GROUP_DEFAULT:
11923                    schedGroup = 'F';
11924                    break;
11925                default:
11926                    schedGroup = '?';
11927                    break;
11928            }
11929            char foreground;
11930            if (r.foregroundActivities) {
11931                foreground = 'A';
11932            } else if (r.foregroundServices) {
11933                foreground = 'S';
11934            } else {
11935                foreground = ' ';
11936            }
11937            String procState = ProcessList.makeProcStateString(r.curProcState);
11938            pw.print(prefix);
11939            pw.print(r.persistent ? persistentLabel : normalLabel);
11940            pw.print(" #");
11941            int num = (origList.size()-1)-list.get(i).second;
11942            if (num < 10) pw.print(' ');
11943            pw.print(num);
11944            pw.print(": ");
11945            pw.print(oomAdj);
11946            pw.print(' ');
11947            pw.print(schedGroup);
11948            pw.print('/');
11949            pw.print(foreground);
11950            pw.print('/');
11951            pw.print(procState);
11952            pw.print(" trm:");
11953            if (r.trimMemoryLevel < 10) pw.print(' ');
11954            pw.print(r.trimMemoryLevel);
11955            pw.print(' ');
11956            pw.print(r.toShortString());
11957            pw.print(" (");
11958            pw.print(r.adjType);
11959            pw.println(')');
11960            if (r.adjSource != null || r.adjTarget != null) {
11961                pw.print(prefix);
11962                pw.print("    ");
11963                if (r.adjTarget instanceof ComponentName) {
11964                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11965                } else if (r.adjTarget != null) {
11966                    pw.print(r.adjTarget.toString());
11967                } else {
11968                    pw.print("{null}");
11969                }
11970                pw.print("<=");
11971                if (r.adjSource instanceof ProcessRecord) {
11972                    pw.print("Proc{");
11973                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11974                    pw.println("}");
11975                } else if (r.adjSource != null) {
11976                    pw.println(r.adjSource.toString());
11977                } else {
11978                    pw.println("{null}");
11979                }
11980            }
11981            if (inclDetails) {
11982                pw.print(prefix);
11983                pw.print("    ");
11984                pw.print("oom: max="); pw.print(r.maxAdj);
11985                pw.print(" curRaw="); pw.print(r.curRawAdj);
11986                pw.print(" setRaw="); pw.print(r.setRawAdj);
11987                pw.print(" cur="); pw.print(r.curAdj);
11988                pw.print(" set="); pw.println(r.setAdj);
11989                pw.print(prefix);
11990                pw.print("    ");
11991                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11992                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11993                pw.print(" lastPss="); pw.print(r.lastPss);
11994                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11995                pw.print(prefix);
11996                pw.print("    ");
11997                pw.print("keeping="); pw.print(r.keeping);
11998                pw.print(" cached="); pw.print(r.cached);
11999                pw.print(" empty="); pw.print(r.empty);
12000                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12001
12002                if (!r.keeping) {
12003                    if (r.lastWakeTime != 0) {
12004                        long wtime;
12005                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12006                        synchronized (stats) {
12007                            wtime = stats.getProcessWakeTime(r.info.uid,
12008                                    r.pid, curRealtime);
12009                        }
12010                        long timeUsed = wtime - r.lastWakeTime;
12011                        pw.print(prefix);
12012                        pw.print("    ");
12013                        pw.print("keep awake over ");
12014                        TimeUtils.formatDuration(realtimeSince, pw);
12015                        pw.print(" used ");
12016                        TimeUtils.formatDuration(timeUsed, pw);
12017                        pw.print(" (");
12018                        pw.print((timeUsed*100)/realtimeSince);
12019                        pw.println("%)");
12020                    }
12021                    if (r.lastCpuTime != 0) {
12022                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12023                        pw.print(prefix);
12024                        pw.print("    ");
12025                        pw.print("run cpu over ");
12026                        TimeUtils.formatDuration(uptimeSince, pw);
12027                        pw.print(" used ");
12028                        TimeUtils.formatDuration(timeUsed, pw);
12029                        pw.print(" (");
12030                        pw.print((timeUsed*100)/uptimeSince);
12031                        pw.println("%)");
12032                    }
12033                }
12034            }
12035        }
12036        return true;
12037    }
12038
12039    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12040        ArrayList<ProcessRecord> procs;
12041        synchronized (this) {
12042            if (args != null && args.length > start
12043                    && args[start].charAt(0) != '-') {
12044                procs = new ArrayList<ProcessRecord>();
12045                int pid = -1;
12046                try {
12047                    pid = Integer.parseInt(args[start]);
12048                } catch (NumberFormatException e) {
12049                }
12050                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12051                    ProcessRecord proc = mLruProcesses.get(i);
12052                    if (proc.pid == pid) {
12053                        procs.add(proc);
12054                    } else if (proc.processName.equals(args[start])) {
12055                        procs.add(proc);
12056                    }
12057                }
12058                if (procs.size() <= 0) {
12059                    return null;
12060                }
12061            } else {
12062                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12063            }
12064        }
12065        return procs;
12066    }
12067
12068    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12069            PrintWriter pw, String[] args) {
12070        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12071        if (procs == null) {
12072            pw.println("No process found for: " + args[0]);
12073            return;
12074        }
12075
12076        long uptime = SystemClock.uptimeMillis();
12077        long realtime = SystemClock.elapsedRealtime();
12078        pw.println("Applications Graphics Acceleration Info:");
12079        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12080
12081        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12082            ProcessRecord r = procs.get(i);
12083            if (r.thread != null) {
12084                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12085                pw.flush();
12086                try {
12087                    TransferPipe tp = new TransferPipe();
12088                    try {
12089                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12090                        tp.go(fd);
12091                    } finally {
12092                        tp.kill();
12093                    }
12094                } catch (IOException e) {
12095                    pw.println("Failure while dumping the app: " + r);
12096                    pw.flush();
12097                } catch (RemoteException e) {
12098                    pw.println("Got a RemoteException while dumping the app " + r);
12099                    pw.flush();
12100                }
12101            }
12102        }
12103    }
12104
12105    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12106        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12107        if (procs == null) {
12108            pw.println("No process found for: " + args[0]);
12109            return;
12110        }
12111
12112        pw.println("Applications Database Info:");
12113
12114        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12115            ProcessRecord r = procs.get(i);
12116            if (r.thread != null) {
12117                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12118                pw.flush();
12119                try {
12120                    TransferPipe tp = new TransferPipe();
12121                    try {
12122                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12123                        tp.go(fd);
12124                    } finally {
12125                        tp.kill();
12126                    }
12127                } catch (IOException e) {
12128                    pw.println("Failure while dumping the app: " + r);
12129                    pw.flush();
12130                } catch (RemoteException e) {
12131                    pw.println("Got a RemoteException while dumping the app " + r);
12132                    pw.flush();
12133                }
12134            }
12135        }
12136    }
12137
12138    final static class MemItem {
12139        final boolean isProc;
12140        final String label;
12141        final String shortLabel;
12142        final long pss;
12143        final int id;
12144        final boolean hasActivities;
12145        ArrayList<MemItem> subitems;
12146
12147        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12148                boolean _hasActivities) {
12149            isProc = true;
12150            label = _label;
12151            shortLabel = _shortLabel;
12152            pss = _pss;
12153            id = _id;
12154            hasActivities = _hasActivities;
12155        }
12156
12157        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12158            isProc = false;
12159            label = _label;
12160            shortLabel = _shortLabel;
12161            pss = _pss;
12162            id = _id;
12163            hasActivities = false;
12164        }
12165    }
12166
12167    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12168            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12169        if (sort && !isCompact) {
12170            Collections.sort(items, new Comparator<MemItem>() {
12171                @Override
12172                public int compare(MemItem lhs, MemItem rhs) {
12173                    if (lhs.pss < rhs.pss) {
12174                        return 1;
12175                    } else if (lhs.pss > rhs.pss) {
12176                        return -1;
12177                    }
12178                    return 0;
12179                }
12180            });
12181        }
12182
12183        for (int i=0; i<items.size(); i++) {
12184            MemItem mi = items.get(i);
12185            if (!isCompact) {
12186                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12187            } else if (mi.isProc) {
12188                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12189                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12190                pw.println(mi.hasActivities ? ",a" : ",e");
12191            } else {
12192                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12193                pw.println(mi.pss);
12194            }
12195            if (mi.subitems != null) {
12196                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12197                        true, isCompact);
12198            }
12199        }
12200    }
12201
12202    // These are in KB.
12203    static final long[] DUMP_MEM_BUCKETS = new long[] {
12204        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12205        120*1024, 160*1024, 200*1024,
12206        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12207        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12208    };
12209
12210    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12211            boolean stackLike) {
12212        int start = label.lastIndexOf('.');
12213        if (start >= 0) start++;
12214        else start = 0;
12215        int end = label.length();
12216        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12217            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12218                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12219                out.append(bucket);
12220                out.append(stackLike ? "MB." : "MB ");
12221                out.append(label, start, end);
12222                return;
12223            }
12224        }
12225        out.append(memKB/1024);
12226        out.append(stackLike ? "MB." : "MB ");
12227        out.append(label, start, end);
12228    }
12229
12230    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12231            ProcessList.NATIVE_ADJ,
12232            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12233            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12234            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12235            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12236            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12237    };
12238    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12239            "Native",
12240            "System", "Persistent", "Foreground",
12241            "Visible", "Perceptible",
12242            "Heavy Weight", "Backup",
12243            "A Services", "Home",
12244            "Previous", "B Services", "Cached"
12245    };
12246    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12247            "native",
12248            "sys", "pers", "fore",
12249            "vis", "percept",
12250            "heavy", "backup",
12251            "servicea", "home",
12252            "prev", "serviceb", "cached"
12253    };
12254
12255    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12256            long realtime, boolean isCheckinRequest, boolean isCompact) {
12257        if (isCheckinRequest || isCompact) {
12258            // short checkin version
12259            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12260        } else {
12261            pw.println("Applications Memory Usage (kB):");
12262            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12263        }
12264    }
12265
12266    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12267            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12268        boolean dumpDetails = false;
12269        boolean dumpFullDetails = false;
12270        boolean dumpDalvik = false;
12271        boolean oomOnly = false;
12272        boolean isCompact = false;
12273        boolean localOnly = false;
12274
12275        int opti = 0;
12276        while (opti < args.length) {
12277            String opt = args[opti];
12278            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12279                break;
12280            }
12281            opti++;
12282            if ("-a".equals(opt)) {
12283                dumpDetails = true;
12284                dumpFullDetails = true;
12285                dumpDalvik = true;
12286            } else if ("-d".equals(opt)) {
12287                dumpDalvik = true;
12288            } else if ("-c".equals(opt)) {
12289                isCompact = true;
12290            } else if ("--oom".equals(opt)) {
12291                oomOnly = true;
12292            } else if ("--local".equals(opt)) {
12293                localOnly = true;
12294            } else if ("-h".equals(opt)) {
12295                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12296                pw.println("  -a: include all available information for each process.");
12297                pw.println("  -d: include dalvik details when dumping process details.");
12298                pw.println("  -c: dump in a compact machine-parseable representation.");
12299                pw.println("  --oom: only show processes organized by oom adj.");
12300                pw.println("  --local: only collect details locally, don't call process.");
12301                pw.println("If [process] is specified it can be the name or ");
12302                pw.println("pid of a specific process to dump.");
12303                return;
12304            } else {
12305                pw.println("Unknown argument: " + opt + "; use -h for help");
12306            }
12307        }
12308
12309        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12310        long uptime = SystemClock.uptimeMillis();
12311        long realtime = SystemClock.elapsedRealtime();
12312        final long[] tmpLong = new long[1];
12313
12314        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12315        if (procs == null) {
12316            // No Java processes.  Maybe they want to print a native process.
12317            if (args != null && args.length > opti
12318                    && args[opti].charAt(0) != '-') {
12319                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12320                        = new ArrayList<ProcessCpuTracker.Stats>();
12321                updateCpuStatsNow();
12322                int findPid = -1;
12323                try {
12324                    findPid = Integer.parseInt(args[opti]);
12325                } catch (NumberFormatException e) {
12326                }
12327                synchronized (mProcessCpuThread) {
12328                    final int N = mProcessCpuTracker.countStats();
12329                    for (int i=0; i<N; i++) {
12330                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12331                        if (st.pid == findPid || (st.baseName != null
12332                                && st.baseName.equals(args[opti]))) {
12333                            nativeProcs.add(st);
12334                        }
12335                    }
12336                }
12337                if (nativeProcs.size() > 0) {
12338                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12339                            isCompact);
12340                    Debug.MemoryInfo mi = null;
12341                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12342                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12343                        final int pid = r.pid;
12344                        if (!isCheckinRequest && dumpDetails) {
12345                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12346                        }
12347                        if (mi == null) {
12348                            mi = new Debug.MemoryInfo();
12349                        }
12350                        if (dumpDetails || (!brief && !oomOnly)) {
12351                            Debug.getMemoryInfo(pid, mi);
12352                        } else {
12353                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12354                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12355                        }
12356                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12357                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12358                        if (isCheckinRequest) {
12359                            pw.println();
12360                        }
12361                    }
12362                    return;
12363                }
12364            }
12365            pw.println("No process found for: " + args[opti]);
12366            return;
12367        }
12368
12369        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12370            dumpDetails = true;
12371        }
12372
12373        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12374
12375        String[] innerArgs = new String[args.length-opti];
12376        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12377
12378        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12379        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12380        long nativePss=0, dalvikPss=0, otherPss=0;
12381        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12382
12383        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12384        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12385                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12386
12387        long totalPss = 0;
12388        long cachedPss = 0;
12389
12390        Debug.MemoryInfo mi = null;
12391        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12392            final ProcessRecord r = procs.get(i);
12393            final IApplicationThread thread;
12394            final int pid;
12395            final int oomAdj;
12396            final boolean hasActivities;
12397            synchronized (this) {
12398                thread = r.thread;
12399                pid = r.pid;
12400                oomAdj = r.getSetAdjWithServices();
12401                hasActivities = r.activities.size() > 0;
12402            }
12403            if (thread != null) {
12404                if (!isCheckinRequest && dumpDetails) {
12405                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12406                }
12407                if (mi == null) {
12408                    mi = new Debug.MemoryInfo();
12409                }
12410                if (dumpDetails || (!brief && !oomOnly)) {
12411                    Debug.getMemoryInfo(pid, mi);
12412                } else {
12413                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12414                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12415                }
12416                if (dumpDetails) {
12417                    if (localOnly) {
12418                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12419                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12420                        if (isCheckinRequest) {
12421                            pw.println();
12422                        }
12423                    } else {
12424                        try {
12425                            pw.flush();
12426                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12427                                    dumpDalvik, innerArgs);
12428                        } catch (RemoteException e) {
12429                            if (!isCheckinRequest) {
12430                                pw.println("Got RemoteException!");
12431                                pw.flush();
12432                            }
12433                        }
12434                    }
12435                }
12436
12437                final long myTotalPss = mi.getTotalPss();
12438                final long myTotalUss = mi.getTotalUss();
12439
12440                synchronized (this) {
12441                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12442                        // Record this for posterity if the process has been stable.
12443                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12444                    }
12445                }
12446
12447                if (!isCheckinRequest && mi != null) {
12448                    totalPss += myTotalPss;
12449                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12450                            (hasActivities ? " / activities)" : ")"),
12451                            r.processName, myTotalPss, pid, hasActivities);
12452                    procMems.add(pssItem);
12453                    procMemsMap.put(pid, pssItem);
12454
12455                    nativePss += mi.nativePss;
12456                    dalvikPss += mi.dalvikPss;
12457                    otherPss += mi.otherPss;
12458                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12459                        long mem = mi.getOtherPss(j);
12460                        miscPss[j] += mem;
12461                        otherPss -= mem;
12462                    }
12463
12464                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12465                        cachedPss += myTotalPss;
12466                    }
12467
12468                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12469                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12470                                || oomIndex == (oomPss.length-1)) {
12471                            oomPss[oomIndex] += myTotalPss;
12472                            if (oomProcs[oomIndex] == null) {
12473                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12474                            }
12475                            oomProcs[oomIndex].add(pssItem);
12476                            break;
12477                        }
12478                    }
12479                }
12480            }
12481        }
12482
12483        if (!isCheckinRequest && procs.size() > 1) {
12484            // If we are showing aggregations, also look for native processes to
12485            // include so that our aggregations are more accurate.
12486            updateCpuStatsNow();
12487            synchronized (mProcessCpuThread) {
12488                final int N = mProcessCpuTracker.countStats();
12489                for (int i=0; i<N; i++) {
12490                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12491                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12492                        if (mi == null) {
12493                            mi = new Debug.MemoryInfo();
12494                        }
12495                        if (!brief && !oomOnly) {
12496                            Debug.getMemoryInfo(st.pid, mi);
12497                        } else {
12498                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12499                            mi.nativePrivateDirty = (int)tmpLong[0];
12500                        }
12501
12502                        final long myTotalPss = mi.getTotalPss();
12503                        totalPss += myTotalPss;
12504
12505                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12506                                st.name, myTotalPss, st.pid, false);
12507                        procMems.add(pssItem);
12508
12509                        nativePss += mi.nativePss;
12510                        dalvikPss += mi.dalvikPss;
12511                        otherPss += mi.otherPss;
12512                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12513                            long mem = mi.getOtherPss(j);
12514                            miscPss[j] += mem;
12515                            otherPss -= mem;
12516                        }
12517                        oomPss[0] += myTotalPss;
12518                        if (oomProcs[0] == null) {
12519                            oomProcs[0] = new ArrayList<MemItem>();
12520                        }
12521                        oomProcs[0].add(pssItem);
12522                    }
12523                }
12524            }
12525
12526            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12527
12528            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12529            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12530            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12531            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12532                String label = Debug.MemoryInfo.getOtherLabel(j);
12533                catMems.add(new MemItem(label, label, miscPss[j], j));
12534            }
12535
12536            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12537            for (int j=0; j<oomPss.length; j++) {
12538                if (oomPss[j] != 0) {
12539                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12540                            : DUMP_MEM_OOM_LABEL[j];
12541                    MemItem item = new MemItem(label, label, oomPss[j],
12542                            DUMP_MEM_OOM_ADJ[j]);
12543                    item.subitems = oomProcs[j];
12544                    oomMems.add(item);
12545                }
12546            }
12547
12548            if (!brief && !oomOnly && !isCompact) {
12549                pw.println();
12550                pw.println("Total PSS by process:");
12551                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12552                pw.println();
12553            }
12554            if (!isCompact) {
12555                pw.println("Total PSS by OOM adjustment:");
12556            }
12557            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12558            if (!brief && !oomOnly) {
12559                PrintWriter out = categoryPw != null ? categoryPw : pw;
12560                if (!isCompact) {
12561                    out.println();
12562                    out.println("Total PSS by category:");
12563                }
12564                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12565            }
12566            if (!isCompact) {
12567                pw.println();
12568            }
12569            MemInfoReader memInfo = new MemInfoReader();
12570            memInfo.readMemInfo();
12571            if (!brief) {
12572                if (!isCompact) {
12573                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12574                    pw.print(" kB (status ");
12575                    switch (mLastMemoryLevel) {
12576                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12577                            pw.println("normal)");
12578                            break;
12579                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12580                            pw.println("moderate)");
12581                            break;
12582                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12583                            pw.println("low)");
12584                            break;
12585                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12586                            pw.println("critical)");
12587                            break;
12588                        default:
12589                            pw.print(mLastMemoryLevel);
12590                            pw.println(")");
12591                            break;
12592                    }
12593                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12594                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12595                            pw.print(cachedPss); pw.print(" cached pss + ");
12596                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12597                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12598                } else {
12599                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12600                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12601                            + memInfo.getFreeSizeKb()); pw.print(",");
12602                    pw.println(totalPss - cachedPss);
12603                }
12604            }
12605            if (!isCompact) {
12606                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12607                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12608                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12609                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12610                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12611                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12612                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12613                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12614                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12615                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12616                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12617            }
12618            if (!brief) {
12619                if (memInfo.getZramTotalSizeKb() != 0) {
12620                    if (!isCompact) {
12621                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12622                                pw.print(" kB physical used for ");
12623                                pw.print(memInfo.getSwapTotalSizeKb()
12624                                        - memInfo.getSwapFreeSizeKb());
12625                                pw.print(" kB in swap (");
12626                                pw.print(memInfo.getSwapTotalSizeKb());
12627                                pw.println(" kB total swap)");
12628                    } else {
12629                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12630                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12631                                pw.println(memInfo.getSwapFreeSizeKb());
12632                    }
12633                }
12634                final int[] SINGLE_LONG_FORMAT = new int[] {
12635                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12636                };
12637                long[] longOut = new long[1];
12638                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12639                        SINGLE_LONG_FORMAT, null, longOut, null);
12640                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12641                longOut[0] = 0;
12642                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12643                        SINGLE_LONG_FORMAT, null, longOut, null);
12644                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12645                longOut[0] = 0;
12646                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12647                        SINGLE_LONG_FORMAT, null, longOut, null);
12648                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12649                longOut[0] = 0;
12650                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12651                        SINGLE_LONG_FORMAT, null, longOut, null);
12652                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12653                if (!isCompact) {
12654                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12655                        pw.print("      KSM: "); pw.print(sharing);
12656                                pw.print(" kB saved from shared ");
12657                                pw.print(shared); pw.println(" kB");
12658                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12659                                pw.print(voltile); pw.println(" kB volatile");
12660                    }
12661                    pw.print("   Tuning: ");
12662                    pw.print(ActivityManager.staticGetMemoryClass());
12663                    pw.print(" (large ");
12664                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12665                    pw.print("), oom ");
12666                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12667                    pw.print(" kB");
12668                    pw.print(", restore limit ");
12669                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12670                    pw.print(" kB");
12671                    if (ActivityManager.isLowRamDeviceStatic()) {
12672                        pw.print(" (low-ram)");
12673                    }
12674                    if (ActivityManager.isHighEndGfx()) {
12675                        pw.print(" (high-end-gfx)");
12676                    }
12677                    pw.println();
12678                } else {
12679                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12680                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12681                    pw.println(voltile);
12682                    pw.print("tuning,");
12683                    pw.print(ActivityManager.staticGetMemoryClass());
12684                    pw.print(',');
12685                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12686                    pw.print(',');
12687                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12688                    if (ActivityManager.isLowRamDeviceStatic()) {
12689                        pw.print(",low-ram");
12690                    }
12691                    if (ActivityManager.isHighEndGfx()) {
12692                        pw.print(",high-end-gfx");
12693                    }
12694                    pw.println();
12695                }
12696            }
12697        }
12698    }
12699
12700    /**
12701     * Searches array of arguments for the specified string
12702     * @param args array of argument strings
12703     * @param value value to search for
12704     * @return true if the value is contained in the array
12705     */
12706    private static boolean scanArgs(String[] args, String value) {
12707        if (args != null) {
12708            for (String arg : args) {
12709                if (value.equals(arg)) {
12710                    return true;
12711                }
12712            }
12713        }
12714        return false;
12715    }
12716
12717    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12718            ContentProviderRecord cpr, boolean always) {
12719        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12720
12721        if (!inLaunching || always) {
12722            synchronized (cpr) {
12723                cpr.launchingApp = null;
12724                cpr.notifyAll();
12725            }
12726            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12727            String names[] = cpr.info.authority.split(";");
12728            for (int j = 0; j < names.length; j++) {
12729                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12730            }
12731        }
12732
12733        for (int i=0; i<cpr.connections.size(); i++) {
12734            ContentProviderConnection conn = cpr.connections.get(i);
12735            if (conn.waiting) {
12736                // If this connection is waiting for the provider, then we don't
12737                // need to mess with its process unless we are always removing
12738                // or for some reason the provider is not currently launching.
12739                if (inLaunching && !always) {
12740                    continue;
12741                }
12742            }
12743            ProcessRecord capp = conn.client;
12744            conn.dead = true;
12745            if (conn.stableCount > 0) {
12746                if (!capp.persistent && capp.thread != null
12747                        && capp.pid != 0
12748                        && capp.pid != MY_PID) {
12749                    killUnneededProcessLocked(capp, "depends on provider "
12750                            + cpr.name.flattenToShortString()
12751                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12752                }
12753            } else if (capp.thread != null && conn.provider.provider != null) {
12754                try {
12755                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12756                } catch (RemoteException e) {
12757                }
12758                // In the protocol here, we don't expect the client to correctly
12759                // clean up this connection, we'll just remove it.
12760                cpr.connections.remove(i);
12761                conn.client.conProviders.remove(conn);
12762            }
12763        }
12764
12765        if (inLaunching && always) {
12766            mLaunchingProviders.remove(cpr);
12767        }
12768        return inLaunching;
12769    }
12770
12771    /**
12772     * Main code for cleaning up a process when it has gone away.  This is
12773     * called both as a result of the process dying, or directly when stopping
12774     * a process when running in single process mode.
12775     */
12776    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12777            boolean restarting, boolean allowRestart, int index) {
12778        if (index >= 0) {
12779            removeLruProcessLocked(app);
12780            ProcessList.remove(app.pid);
12781        }
12782
12783        mProcessesToGc.remove(app);
12784        mPendingPssProcesses.remove(app);
12785
12786        // Dismiss any open dialogs.
12787        if (app.crashDialog != null && !app.forceCrashReport) {
12788            app.crashDialog.dismiss();
12789            app.crashDialog = null;
12790        }
12791        if (app.anrDialog != null) {
12792            app.anrDialog.dismiss();
12793            app.anrDialog = null;
12794        }
12795        if (app.waitDialog != null) {
12796            app.waitDialog.dismiss();
12797            app.waitDialog = null;
12798        }
12799
12800        app.crashing = false;
12801        app.notResponding = false;
12802
12803        app.resetPackageList(mProcessStats);
12804        app.unlinkDeathRecipient();
12805        app.makeInactive(mProcessStats);
12806        app.forcingToForeground = null;
12807        updateProcessForegroundLocked(app, false, false);
12808        app.foregroundActivities = false;
12809        app.hasShownUi = false;
12810        app.treatLikeActivity = false;
12811        app.hasAboveClient = false;
12812        app.hasClientActivities = false;
12813
12814        mServices.killServicesLocked(app, allowRestart);
12815
12816        boolean restart = false;
12817
12818        // Remove published content providers.
12819        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12820            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12821            final boolean always = app.bad || !allowRestart;
12822            if (removeDyingProviderLocked(app, cpr, always) || always) {
12823                // We left the provider in the launching list, need to
12824                // restart it.
12825                restart = true;
12826            }
12827
12828            cpr.provider = null;
12829            cpr.proc = null;
12830        }
12831        app.pubProviders.clear();
12832
12833        // Take care of any launching providers waiting for this process.
12834        if (checkAppInLaunchingProvidersLocked(app, false)) {
12835            restart = true;
12836        }
12837
12838        // Unregister from connected content providers.
12839        if (!app.conProviders.isEmpty()) {
12840            for (int i=0; i<app.conProviders.size(); i++) {
12841                ContentProviderConnection conn = app.conProviders.get(i);
12842                conn.provider.connections.remove(conn);
12843            }
12844            app.conProviders.clear();
12845        }
12846
12847        // At this point there may be remaining entries in mLaunchingProviders
12848        // where we were the only one waiting, so they are no longer of use.
12849        // Look for these and clean up if found.
12850        // XXX Commented out for now.  Trying to figure out a way to reproduce
12851        // the actual situation to identify what is actually going on.
12852        if (false) {
12853            for (int i=0; i<mLaunchingProviders.size(); i++) {
12854                ContentProviderRecord cpr = (ContentProviderRecord)
12855                        mLaunchingProviders.get(i);
12856                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12857                    synchronized (cpr) {
12858                        cpr.launchingApp = null;
12859                        cpr.notifyAll();
12860                    }
12861                }
12862            }
12863        }
12864
12865        skipCurrentReceiverLocked(app);
12866
12867        // Unregister any receivers.
12868        for (int i=app.receivers.size()-1; i>=0; i--) {
12869            removeReceiverLocked(app.receivers.valueAt(i));
12870        }
12871        app.receivers.clear();
12872
12873        // If the app is undergoing backup, tell the backup manager about it
12874        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12875            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12876                    + mBackupTarget.appInfo + " died during backup");
12877            try {
12878                IBackupManager bm = IBackupManager.Stub.asInterface(
12879                        ServiceManager.getService(Context.BACKUP_SERVICE));
12880                bm.agentDisconnected(app.info.packageName);
12881            } catch (RemoteException e) {
12882                // can't happen; backup manager is local
12883            }
12884        }
12885
12886        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12887            ProcessChangeItem item = mPendingProcessChanges.get(i);
12888            if (item.pid == app.pid) {
12889                mPendingProcessChanges.remove(i);
12890                mAvailProcessChanges.add(item);
12891            }
12892        }
12893        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12894
12895        // If the caller is restarting this app, then leave it in its
12896        // current lists and let the caller take care of it.
12897        if (restarting) {
12898            return;
12899        }
12900
12901        if (!app.persistent || app.isolated) {
12902            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12903                    "Removing non-persistent process during cleanup: " + app);
12904            mProcessNames.remove(app.processName, app.uid);
12905            mIsolatedProcesses.remove(app.uid);
12906            if (mHeavyWeightProcess == app) {
12907                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12908                        mHeavyWeightProcess.userId, 0));
12909                mHeavyWeightProcess = null;
12910            }
12911        } else if (!app.removed) {
12912            // This app is persistent, so we need to keep its record around.
12913            // If it is not already on the pending app list, add it there
12914            // and start a new process for it.
12915            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12916                mPersistentStartingProcesses.add(app);
12917                restart = true;
12918            }
12919        }
12920        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12921                "Clean-up removing on hold: " + app);
12922        mProcessesOnHold.remove(app);
12923
12924        if (app == mHomeProcess) {
12925            mHomeProcess = null;
12926        }
12927        if (app == mPreviousProcess) {
12928            mPreviousProcess = null;
12929        }
12930
12931        if (restart && !app.isolated) {
12932            // We have components that still need to be running in the
12933            // process, so re-launch it.
12934            mProcessNames.put(app.processName, app.uid, app);
12935            startProcessLocked(app, "restart", app.processName);
12936        } else if (app.pid > 0 && app.pid != MY_PID) {
12937            // Goodbye!
12938            boolean removed;
12939            synchronized (mPidsSelfLocked) {
12940                mPidsSelfLocked.remove(app.pid);
12941                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12942            }
12943            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12944                    app.processName, app.info.uid);
12945            if (app.isolated) {
12946                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12947            }
12948            app.setPid(0);
12949        }
12950    }
12951
12952    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12953        // Look through the content providers we are waiting to have launched,
12954        // and if any run in this process then either schedule a restart of
12955        // the process or kill the client waiting for it if this process has
12956        // gone bad.
12957        int NL = mLaunchingProviders.size();
12958        boolean restart = false;
12959        for (int i=0; i<NL; i++) {
12960            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12961            if (cpr.launchingApp == app) {
12962                if (!alwaysBad && !app.bad) {
12963                    restart = true;
12964                } else {
12965                    removeDyingProviderLocked(app, cpr, true);
12966                    // cpr should have been removed from mLaunchingProviders
12967                    NL = mLaunchingProviders.size();
12968                    i--;
12969                }
12970            }
12971        }
12972        return restart;
12973    }
12974
12975    // =========================================================
12976    // SERVICES
12977    // =========================================================
12978
12979    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12980            int flags) {
12981        enforceNotIsolatedCaller("getServices");
12982        synchronized (this) {
12983            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12984        }
12985    }
12986
12987    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12988        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12989        synchronized (this) {
12990            return mServices.getRunningServiceControlPanelLocked(name);
12991        }
12992    }
12993
12994    public ComponentName startService(IApplicationThread caller, Intent service,
12995            String resolvedType, int userId) {
12996        enforceNotIsolatedCaller("startService");
12997        // Refuse possible leaked file descriptors
12998        if (service != null && service.hasFileDescriptors() == true) {
12999            throw new IllegalArgumentException("File descriptors passed in Intent");
13000        }
13001
13002        if (DEBUG_SERVICE)
13003            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13004        synchronized(this) {
13005            final int callingPid = Binder.getCallingPid();
13006            final int callingUid = Binder.getCallingUid();
13007            final long origId = Binder.clearCallingIdentity();
13008            ComponentName res = mServices.startServiceLocked(caller, service,
13009                    resolvedType, callingPid, callingUid, userId);
13010            Binder.restoreCallingIdentity(origId);
13011            return res;
13012        }
13013    }
13014
13015    ComponentName startServiceInPackage(int uid,
13016            Intent service, String resolvedType, int userId) {
13017        synchronized(this) {
13018            if (DEBUG_SERVICE)
13019                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13020            final long origId = Binder.clearCallingIdentity();
13021            ComponentName res = mServices.startServiceLocked(null, service,
13022                    resolvedType, -1, uid, userId);
13023            Binder.restoreCallingIdentity(origId);
13024            return res;
13025        }
13026    }
13027
13028    public int stopService(IApplicationThread caller, Intent service,
13029            String resolvedType, int userId) {
13030        enforceNotIsolatedCaller("stopService");
13031        // Refuse possible leaked file descriptors
13032        if (service != null && service.hasFileDescriptors() == true) {
13033            throw new IllegalArgumentException("File descriptors passed in Intent");
13034        }
13035
13036        synchronized(this) {
13037            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13038        }
13039    }
13040
13041    public IBinder peekService(Intent service, String resolvedType) {
13042        enforceNotIsolatedCaller("peekService");
13043        // Refuse possible leaked file descriptors
13044        if (service != null && service.hasFileDescriptors() == true) {
13045            throw new IllegalArgumentException("File descriptors passed in Intent");
13046        }
13047        synchronized(this) {
13048            return mServices.peekServiceLocked(service, resolvedType);
13049        }
13050    }
13051
13052    public boolean stopServiceToken(ComponentName className, IBinder token,
13053            int startId) {
13054        synchronized(this) {
13055            return mServices.stopServiceTokenLocked(className, token, startId);
13056        }
13057    }
13058
13059    public void setServiceForeground(ComponentName className, IBinder token,
13060            int id, Notification notification, boolean removeNotification) {
13061        synchronized(this) {
13062            mServices.setServiceForegroundLocked(className, token, id, notification,
13063                    removeNotification);
13064        }
13065    }
13066
13067    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13068            boolean requireFull, String name, String callerPackage) {
13069        final int callingUserId = UserHandle.getUserId(callingUid);
13070        if (callingUserId != userId) {
13071            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13072                if ((requireFull || checkComponentPermission(
13073                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13074                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13075                        && checkComponentPermission(
13076                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13077                                callingPid, callingUid, -1, true)
13078                                != PackageManager.PERMISSION_GRANTED) {
13079                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13080                        // In this case, they would like to just execute as their
13081                        // owner user instead of failing.
13082                        userId = callingUserId;
13083                    } else {
13084                        StringBuilder builder = new StringBuilder(128);
13085                        builder.append("Permission Denial: ");
13086                        builder.append(name);
13087                        if (callerPackage != null) {
13088                            builder.append(" from ");
13089                            builder.append(callerPackage);
13090                        }
13091                        builder.append(" asks to run as user ");
13092                        builder.append(userId);
13093                        builder.append(" but is calling from user ");
13094                        builder.append(UserHandle.getUserId(callingUid));
13095                        builder.append("; this requires ");
13096                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13097                        if (!requireFull) {
13098                            builder.append(" or ");
13099                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13100                        }
13101                        String msg = builder.toString();
13102                        Slog.w(TAG, msg);
13103                        throw new SecurityException(msg);
13104                    }
13105                }
13106            }
13107            if (userId == UserHandle.USER_CURRENT
13108                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13109                // Note that we may be accessing this outside of a lock...
13110                // shouldn't be a big deal, if this is being called outside
13111                // of a locked context there is intrinsically a race with
13112                // the value the caller will receive and someone else changing it.
13113                userId = mCurrentUserId;
13114            }
13115            if (!allowAll && userId < 0) {
13116                throw new IllegalArgumentException(
13117                        "Call does not support special user #" + userId);
13118            }
13119        }
13120        return userId;
13121    }
13122
13123    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13124            String className, int flags) {
13125        boolean result = false;
13126        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13127            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13128                if (ActivityManager.checkUidPermission(
13129                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13130                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13131                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13132                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13133                            + " requests FLAG_SINGLE_USER, but app does not hold "
13134                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13135                    Slog.w(TAG, msg);
13136                    throw new SecurityException(msg);
13137                }
13138                result = true;
13139            }
13140        } else if (componentProcessName == aInfo.packageName) {
13141            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13142        } else if ("system".equals(componentProcessName)) {
13143            result = true;
13144        }
13145        if (DEBUG_MU) {
13146            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13147                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13148        }
13149        return result;
13150    }
13151
13152    public int bindService(IApplicationThread caller, IBinder token,
13153            Intent service, String resolvedType,
13154            IServiceConnection connection, int flags, int userId) {
13155        enforceNotIsolatedCaller("bindService");
13156        // Refuse possible leaked file descriptors
13157        if (service != null && service.hasFileDescriptors() == true) {
13158            throw new IllegalArgumentException("File descriptors passed in Intent");
13159        }
13160
13161        synchronized(this) {
13162            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13163                    connection, flags, userId);
13164        }
13165    }
13166
13167    public boolean unbindService(IServiceConnection connection) {
13168        synchronized (this) {
13169            return mServices.unbindServiceLocked(connection);
13170        }
13171    }
13172
13173    public void publishService(IBinder token, Intent intent, IBinder service) {
13174        // Refuse possible leaked file descriptors
13175        if (intent != null && intent.hasFileDescriptors() == true) {
13176            throw new IllegalArgumentException("File descriptors passed in Intent");
13177        }
13178
13179        synchronized(this) {
13180            if (!(token instanceof ServiceRecord)) {
13181                throw new IllegalArgumentException("Invalid service token");
13182            }
13183            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13184        }
13185    }
13186
13187    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13188        // Refuse possible leaked file descriptors
13189        if (intent != null && intent.hasFileDescriptors() == true) {
13190            throw new IllegalArgumentException("File descriptors passed in Intent");
13191        }
13192
13193        synchronized(this) {
13194            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13195        }
13196    }
13197
13198    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13199        synchronized(this) {
13200            if (!(token instanceof ServiceRecord)) {
13201                throw new IllegalArgumentException("Invalid service token");
13202            }
13203            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13204        }
13205    }
13206
13207    // =========================================================
13208    // BACKUP AND RESTORE
13209    // =========================================================
13210
13211    // Cause the target app to be launched if necessary and its backup agent
13212    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13213    // activity manager to announce its creation.
13214    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13215        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13216        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13217
13218        synchronized(this) {
13219            // !!! TODO: currently no check here that we're already bound
13220            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13221            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13222            synchronized (stats) {
13223                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13224            }
13225
13226            // Backup agent is now in use, its package can't be stopped.
13227            try {
13228                AppGlobals.getPackageManager().setPackageStoppedState(
13229                        app.packageName, false, UserHandle.getUserId(app.uid));
13230            } catch (RemoteException e) {
13231            } catch (IllegalArgumentException e) {
13232                Slog.w(TAG, "Failed trying to unstop package "
13233                        + app.packageName + ": " + e);
13234            }
13235
13236            BackupRecord r = new BackupRecord(ss, app, backupMode);
13237            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13238                    ? new ComponentName(app.packageName, app.backupAgentName)
13239                    : new ComponentName("android", "FullBackupAgent");
13240            // startProcessLocked() returns existing proc's record if it's already running
13241            ProcessRecord proc = startProcessLocked(app.processName, app,
13242                    false, 0, "backup", hostingName, false, false, false);
13243            if (proc == null) {
13244                Slog.e(TAG, "Unable to start backup agent process " + r);
13245                return false;
13246            }
13247
13248            r.app = proc;
13249            mBackupTarget = r;
13250            mBackupAppName = app.packageName;
13251
13252            // Try not to kill the process during backup
13253            updateOomAdjLocked(proc);
13254
13255            // If the process is already attached, schedule the creation of the backup agent now.
13256            // If it is not yet live, this will be done when it attaches to the framework.
13257            if (proc.thread != null) {
13258                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13259                try {
13260                    proc.thread.scheduleCreateBackupAgent(app,
13261                            compatibilityInfoForPackageLocked(app), backupMode);
13262                } catch (RemoteException e) {
13263                    // Will time out on the backup manager side
13264                }
13265            } else {
13266                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13267            }
13268            // Invariants: at this point, the target app process exists and the application
13269            // is either already running or in the process of coming up.  mBackupTarget and
13270            // mBackupAppName describe the app, so that when it binds back to the AM we
13271            // know that it's scheduled for a backup-agent operation.
13272        }
13273
13274        return true;
13275    }
13276
13277    @Override
13278    public void clearPendingBackup() {
13279        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13280        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13281
13282        synchronized (this) {
13283            mBackupTarget = null;
13284            mBackupAppName = null;
13285        }
13286    }
13287
13288    // A backup agent has just come up
13289    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13290        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13291                + " = " + agent);
13292
13293        synchronized(this) {
13294            if (!agentPackageName.equals(mBackupAppName)) {
13295                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13296                return;
13297            }
13298        }
13299
13300        long oldIdent = Binder.clearCallingIdentity();
13301        try {
13302            IBackupManager bm = IBackupManager.Stub.asInterface(
13303                    ServiceManager.getService(Context.BACKUP_SERVICE));
13304            bm.agentConnected(agentPackageName, agent);
13305        } catch (RemoteException e) {
13306            // can't happen; the backup manager service is local
13307        } catch (Exception e) {
13308            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13309            e.printStackTrace();
13310        } finally {
13311            Binder.restoreCallingIdentity(oldIdent);
13312        }
13313    }
13314
13315    // done with this agent
13316    public void unbindBackupAgent(ApplicationInfo appInfo) {
13317        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13318        if (appInfo == null) {
13319            Slog.w(TAG, "unbind backup agent for null app");
13320            return;
13321        }
13322
13323        synchronized(this) {
13324            try {
13325                if (mBackupAppName == null) {
13326                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13327                    return;
13328                }
13329
13330                if (!mBackupAppName.equals(appInfo.packageName)) {
13331                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13332                    return;
13333                }
13334
13335                // Not backing this app up any more; reset its OOM adjustment
13336                final ProcessRecord proc = mBackupTarget.app;
13337                updateOomAdjLocked(proc);
13338
13339                // If the app crashed during backup, 'thread' will be null here
13340                if (proc.thread != null) {
13341                    try {
13342                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13343                                compatibilityInfoForPackageLocked(appInfo));
13344                    } catch (Exception e) {
13345                        Slog.e(TAG, "Exception when unbinding backup agent:");
13346                        e.printStackTrace();
13347                    }
13348                }
13349            } finally {
13350                mBackupTarget = null;
13351                mBackupAppName = null;
13352            }
13353        }
13354    }
13355    // =========================================================
13356    // BROADCASTS
13357    // =========================================================
13358
13359    private final List getStickiesLocked(String action, IntentFilter filter,
13360            List cur, int userId) {
13361        final ContentResolver resolver = mContext.getContentResolver();
13362        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13363        if (stickies == null) {
13364            return cur;
13365        }
13366        final ArrayList<Intent> list = stickies.get(action);
13367        if (list == null) {
13368            return cur;
13369        }
13370        int N = list.size();
13371        for (int i=0; i<N; i++) {
13372            Intent intent = list.get(i);
13373            if (filter.match(resolver, intent, true, TAG) >= 0) {
13374                if (cur == null) {
13375                    cur = new ArrayList<Intent>();
13376                }
13377                cur.add(intent);
13378            }
13379        }
13380        return cur;
13381    }
13382
13383    boolean isPendingBroadcastProcessLocked(int pid) {
13384        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13385                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13386    }
13387
13388    void skipPendingBroadcastLocked(int pid) {
13389            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13390            for (BroadcastQueue queue : mBroadcastQueues) {
13391                queue.skipPendingBroadcastLocked(pid);
13392            }
13393    }
13394
13395    // The app just attached; send any pending broadcasts that it should receive
13396    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13397        boolean didSomething = false;
13398        for (BroadcastQueue queue : mBroadcastQueues) {
13399            didSomething |= queue.sendPendingBroadcastsLocked(app);
13400        }
13401        return didSomething;
13402    }
13403
13404    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13405            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13406        enforceNotIsolatedCaller("registerReceiver");
13407        int callingUid;
13408        int callingPid;
13409        synchronized(this) {
13410            ProcessRecord callerApp = null;
13411            if (caller != null) {
13412                callerApp = getRecordForAppLocked(caller);
13413                if (callerApp == null) {
13414                    throw new SecurityException(
13415                            "Unable to find app for caller " + caller
13416                            + " (pid=" + Binder.getCallingPid()
13417                            + ") when registering receiver " + receiver);
13418                }
13419                if (callerApp.info.uid != Process.SYSTEM_UID &&
13420                        !callerApp.pkgList.containsKey(callerPackage) &&
13421                        !"android".equals(callerPackage)) {
13422                    throw new SecurityException("Given caller package " + callerPackage
13423                            + " is not running in process " + callerApp);
13424                }
13425                callingUid = callerApp.info.uid;
13426                callingPid = callerApp.pid;
13427            } else {
13428                callerPackage = null;
13429                callingUid = Binder.getCallingUid();
13430                callingPid = Binder.getCallingPid();
13431            }
13432
13433            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13434                    true, true, "registerReceiver", callerPackage);
13435
13436            List allSticky = null;
13437
13438            // Look for any matching sticky broadcasts...
13439            Iterator actions = filter.actionsIterator();
13440            if (actions != null) {
13441                while (actions.hasNext()) {
13442                    String action = (String)actions.next();
13443                    allSticky = getStickiesLocked(action, filter, allSticky,
13444                            UserHandle.USER_ALL);
13445                    allSticky = getStickiesLocked(action, filter, allSticky,
13446                            UserHandle.getUserId(callingUid));
13447                }
13448            } else {
13449                allSticky = getStickiesLocked(null, filter, allSticky,
13450                        UserHandle.USER_ALL);
13451                allSticky = getStickiesLocked(null, filter, allSticky,
13452                        UserHandle.getUserId(callingUid));
13453            }
13454
13455            // The first sticky in the list is returned directly back to
13456            // the client.
13457            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13458
13459            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13460                    + ": " + sticky);
13461
13462            if (receiver == null) {
13463                return sticky;
13464            }
13465
13466            ReceiverList rl
13467                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13468            if (rl == null) {
13469                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13470                        userId, receiver);
13471                if (rl.app != null) {
13472                    rl.app.receivers.add(rl);
13473                } else {
13474                    try {
13475                        receiver.asBinder().linkToDeath(rl, 0);
13476                    } catch (RemoteException e) {
13477                        return sticky;
13478                    }
13479                    rl.linkedToDeath = true;
13480                }
13481                mRegisteredReceivers.put(receiver.asBinder(), rl);
13482            } else if (rl.uid != callingUid) {
13483                throw new IllegalArgumentException(
13484                        "Receiver requested to register for uid " + callingUid
13485                        + " was previously registered for uid " + rl.uid);
13486            } else if (rl.pid != callingPid) {
13487                throw new IllegalArgumentException(
13488                        "Receiver requested to register for pid " + callingPid
13489                        + " was previously registered for pid " + rl.pid);
13490            } else if (rl.userId != userId) {
13491                throw new IllegalArgumentException(
13492                        "Receiver requested to register for user " + userId
13493                        + " was previously registered for user " + rl.userId);
13494            }
13495            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13496                    permission, callingUid, userId);
13497            rl.add(bf);
13498            if (!bf.debugCheck()) {
13499                Slog.w(TAG, "==> For Dynamic broadast");
13500            }
13501            mReceiverResolver.addFilter(bf);
13502
13503            // Enqueue broadcasts for all existing stickies that match
13504            // this filter.
13505            if (allSticky != null) {
13506                ArrayList receivers = new ArrayList();
13507                receivers.add(bf);
13508
13509                int N = allSticky.size();
13510                for (int i=0; i<N; i++) {
13511                    Intent intent = (Intent)allSticky.get(i);
13512                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13513                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13514                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13515                            null, null, false, true, true, -1);
13516                    queue.enqueueParallelBroadcastLocked(r);
13517                    queue.scheduleBroadcastsLocked();
13518                }
13519            }
13520
13521            return sticky;
13522        }
13523    }
13524
13525    public void unregisterReceiver(IIntentReceiver receiver) {
13526        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13527
13528        final long origId = Binder.clearCallingIdentity();
13529        try {
13530            boolean doTrim = false;
13531
13532            synchronized(this) {
13533                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13534                if (rl != null) {
13535                    if (rl.curBroadcast != null) {
13536                        BroadcastRecord r = rl.curBroadcast;
13537                        final boolean doNext = finishReceiverLocked(
13538                                receiver.asBinder(), r.resultCode, r.resultData,
13539                                r.resultExtras, r.resultAbort);
13540                        if (doNext) {
13541                            doTrim = true;
13542                            r.queue.processNextBroadcast(false);
13543                        }
13544                    }
13545
13546                    if (rl.app != null) {
13547                        rl.app.receivers.remove(rl);
13548                    }
13549                    removeReceiverLocked(rl);
13550                    if (rl.linkedToDeath) {
13551                        rl.linkedToDeath = false;
13552                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13553                    }
13554                }
13555            }
13556
13557            // If we actually concluded any broadcasts, we might now be able
13558            // to trim the recipients' apps from our working set
13559            if (doTrim) {
13560                trimApplications();
13561                return;
13562            }
13563
13564        } finally {
13565            Binder.restoreCallingIdentity(origId);
13566        }
13567    }
13568
13569    void removeReceiverLocked(ReceiverList rl) {
13570        mRegisteredReceivers.remove(rl.receiver.asBinder());
13571        int N = rl.size();
13572        for (int i=0; i<N; i++) {
13573            mReceiverResolver.removeFilter(rl.get(i));
13574        }
13575    }
13576
13577    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13578        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13579            ProcessRecord r = mLruProcesses.get(i);
13580            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13581                try {
13582                    r.thread.dispatchPackageBroadcast(cmd, packages);
13583                } catch (RemoteException ex) {
13584                }
13585            }
13586        }
13587    }
13588
13589    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13590            int[] users) {
13591        List<ResolveInfo> receivers = null;
13592        try {
13593            HashSet<ComponentName> singleUserReceivers = null;
13594            boolean scannedFirstReceivers = false;
13595            for (int user : users) {
13596                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13597                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13598                if (user != 0 && newReceivers != null) {
13599                    // If this is not the primary user, we need to check for
13600                    // any receivers that should be filtered out.
13601                    for (int i=0; i<newReceivers.size(); i++) {
13602                        ResolveInfo ri = newReceivers.get(i);
13603                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13604                            newReceivers.remove(i);
13605                            i--;
13606                        }
13607                    }
13608                }
13609                if (newReceivers != null && newReceivers.size() == 0) {
13610                    newReceivers = null;
13611                }
13612                if (receivers == null) {
13613                    receivers = newReceivers;
13614                } else if (newReceivers != null) {
13615                    // We need to concatenate the additional receivers
13616                    // found with what we have do far.  This would be easy,
13617                    // but we also need to de-dup any receivers that are
13618                    // singleUser.
13619                    if (!scannedFirstReceivers) {
13620                        // Collect any single user receivers we had already retrieved.
13621                        scannedFirstReceivers = true;
13622                        for (int i=0; i<receivers.size(); i++) {
13623                            ResolveInfo ri = receivers.get(i);
13624                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13625                                ComponentName cn = new ComponentName(
13626                                        ri.activityInfo.packageName, ri.activityInfo.name);
13627                                if (singleUserReceivers == null) {
13628                                    singleUserReceivers = new HashSet<ComponentName>();
13629                                }
13630                                singleUserReceivers.add(cn);
13631                            }
13632                        }
13633                    }
13634                    // Add the new results to the existing results, tracking
13635                    // and de-dupping single user receivers.
13636                    for (int i=0; i<newReceivers.size(); i++) {
13637                        ResolveInfo ri = newReceivers.get(i);
13638                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13639                            ComponentName cn = new ComponentName(
13640                                    ri.activityInfo.packageName, ri.activityInfo.name);
13641                            if (singleUserReceivers == null) {
13642                                singleUserReceivers = new HashSet<ComponentName>();
13643                            }
13644                            if (!singleUserReceivers.contains(cn)) {
13645                                singleUserReceivers.add(cn);
13646                                receivers.add(ri);
13647                            }
13648                        } else {
13649                            receivers.add(ri);
13650                        }
13651                    }
13652                }
13653            }
13654        } catch (RemoteException ex) {
13655            // pm is in same process, this will never happen.
13656        }
13657        return receivers;
13658    }
13659
13660    private final int broadcastIntentLocked(ProcessRecord callerApp,
13661            String callerPackage, Intent intent, String resolvedType,
13662            IIntentReceiver resultTo, int resultCode, String resultData,
13663            Bundle map, String requiredPermission, int appOp,
13664            boolean ordered, boolean sticky, int callingPid, int callingUid,
13665            int userId) {
13666        intent = new Intent(intent);
13667
13668        // By default broadcasts do not go to stopped apps.
13669        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13670
13671        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13672            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13673            + " ordered=" + ordered + " userid=" + userId);
13674        if ((resultTo != null) && !ordered) {
13675            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13676        }
13677
13678        userId = handleIncomingUser(callingPid, callingUid, userId,
13679                true, false, "broadcast", callerPackage);
13680
13681        // Make sure that the user who is receiving this broadcast is started.
13682        // If not, we will just skip it.
13683        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13684            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13685                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13686                Slog.w(TAG, "Skipping broadcast of " + intent
13687                        + ": user " + userId + " is stopped");
13688                return ActivityManager.BROADCAST_SUCCESS;
13689            }
13690        }
13691
13692        /*
13693         * Prevent non-system code (defined here to be non-persistent
13694         * processes) from sending protected broadcasts.
13695         */
13696        int callingAppId = UserHandle.getAppId(callingUid);
13697        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13698            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13699            callingUid == 0) {
13700            // Always okay.
13701        } else if (callerApp == null || !callerApp.persistent) {
13702            try {
13703                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13704                        intent.getAction())) {
13705                    String msg = "Permission Denial: not allowed to send broadcast "
13706                            + intent.getAction() + " from pid="
13707                            + callingPid + ", uid=" + callingUid;
13708                    Slog.w(TAG, msg);
13709                    throw new SecurityException(msg);
13710                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13711                    // Special case for compatibility: we don't want apps to send this,
13712                    // but historically it has not been protected and apps may be using it
13713                    // to poke their own app widget.  So, instead of making it protected,
13714                    // just limit it to the caller.
13715                    if (callerApp == null) {
13716                        String msg = "Permission Denial: not allowed to send broadcast "
13717                                + intent.getAction() + " from unknown caller.";
13718                        Slog.w(TAG, msg);
13719                        throw new SecurityException(msg);
13720                    } else if (intent.getComponent() != null) {
13721                        // They are good enough to send to an explicit component...  verify
13722                        // it is being sent to the calling app.
13723                        if (!intent.getComponent().getPackageName().equals(
13724                                callerApp.info.packageName)) {
13725                            String msg = "Permission Denial: not allowed to send broadcast "
13726                                    + intent.getAction() + " to "
13727                                    + intent.getComponent().getPackageName() + " from "
13728                                    + callerApp.info.packageName;
13729                            Slog.w(TAG, msg);
13730                            throw new SecurityException(msg);
13731                        }
13732                    } else {
13733                        // Limit broadcast to their own package.
13734                        intent.setPackage(callerApp.info.packageName);
13735                    }
13736                }
13737            } catch (RemoteException e) {
13738                Slog.w(TAG, "Remote exception", e);
13739                return ActivityManager.BROADCAST_SUCCESS;
13740            }
13741        }
13742
13743        // Handle special intents: if this broadcast is from the package
13744        // manager about a package being removed, we need to remove all of
13745        // its activities from the history stack.
13746        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13747                intent.getAction());
13748        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13749                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13750                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13751                || uidRemoved) {
13752            if (checkComponentPermission(
13753                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13754                    callingPid, callingUid, -1, true)
13755                    == PackageManager.PERMISSION_GRANTED) {
13756                if (uidRemoved) {
13757                    final Bundle intentExtras = intent.getExtras();
13758                    final int uid = intentExtras != null
13759                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13760                    if (uid >= 0) {
13761                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13762                        synchronized (bs) {
13763                            bs.removeUidStatsLocked(uid);
13764                        }
13765                        mAppOpsService.uidRemoved(uid);
13766                    }
13767                } else {
13768                    // If resources are unavailable just force stop all
13769                    // those packages and flush the attribute cache as well.
13770                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13771                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13772                        if (list != null && (list.length > 0)) {
13773                            for (String pkg : list) {
13774                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13775                                        "storage unmount");
13776                            }
13777                            sendPackageBroadcastLocked(
13778                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13779                        }
13780                    } else {
13781                        Uri data = intent.getData();
13782                        String ssp;
13783                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13784                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13785                                    intent.getAction());
13786                            boolean fullUninstall = removed &&
13787                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13788                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13789                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13790                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13791                                        false, fullUninstall, userId,
13792                                        removed ? "pkg removed" : "pkg changed");
13793                            }
13794                            if (removed) {
13795                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13796                                        new String[] {ssp}, userId);
13797                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13798                                    mAppOpsService.packageRemoved(
13799                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13800
13801                                    // Remove all permissions granted from/to this package
13802                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13803                                }
13804                            }
13805                        }
13806                    }
13807                }
13808            } else {
13809                String msg = "Permission Denial: " + intent.getAction()
13810                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13811                        + ", uid=" + callingUid + ")"
13812                        + " requires "
13813                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13814                Slog.w(TAG, msg);
13815                throw new SecurityException(msg);
13816            }
13817
13818        // Special case for adding a package: by default turn on compatibility
13819        // mode.
13820        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13821            Uri data = intent.getData();
13822            String ssp;
13823            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13824                mCompatModePackages.handlePackageAddedLocked(ssp,
13825                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13826            }
13827        }
13828
13829        /*
13830         * If this is the time zone changed action, queue up a message that will reset the timezone
13831         * of all currently running processes. This message will get queued up before the broadcast
13832         * happens.
13833         */
13834        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13835            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13836        }
13837
13838        /*
13839         * If the user set the time, let all running processes know.
13840         */
13841        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13842            final int is24Hour = intent.getBooleanExtra(
13843                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13844            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13845        }
13846
13847        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13848            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13849        }
13850
13851        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13852            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13853            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13854        }
13855
13856        // Add to the sticky list if requested.
13857        if (sticky) {
13858            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13859                    callingPid, callingUid)
13860                    != PackageManager.PERMISSION_GRANTED) {
13861                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13862                        + callingPid + ", uid=" + callingUid
13863                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13864                Slog.w(TAG, msg);
13865                throw new SecurityException(msg);
13866            }
13867            if (requiredPermission != null) {
13868                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13869                        + " and enforce permission " + requiredPermission);
13870                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13871            }
13872            if (intent.getComponent() != null) {
13873                throw new SecurityException(
13874                        "Sticky broadcasts can't target a specific component");
13875            }
13876            // We use userId directly here, since the "all" target is maintained
13877            // as a separate set of sticky broadcasts.
13878            if (userId != UserHandle.USER_ALL) {
13879                // But first, if this is not a broadcast to all users, then
13880                // make sure it doesn't conflict with an existing broadcast to
13881                // all users.
13882                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13883                        UserHandle.USER_ALL);
13884                if (stickies != null) {
13885                    ArrayList<Intent> list = stickies.get(intent.getAction());
13886                    if (list != null) {
13887                        int N = list.size();
13888                        int i;
13889                        for (i=0; i<N; i++) {
13890                            if (intent.filterEquals(list.get(i))) {
13891                                throw new IllegalArgumentException(
13892                                        "Sticky broadcast " + intent + " for user "
13893                                        + userId + " conflicts with existing global broadcast");
13894                            }
13895                        }
13896                    }
13897                }
13898            }
13899            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13900            if (stickies == null) {
13901                stickies = new ArrayMap<String, ArrayList<Intent>>();
13902                mStickyBroadcasts.put(userId, stickies);
13903            }
13904            ArrayList<Intent> list = stickies.get(intent.getAction());
13905            if (list == null) {
13906                list = new ArrayList<Intent>();
13907                stickies.put(intent.getAction(), list);
13908            }
13909            int N = list.size();
13910            int i;
13911            for (i=0; i<N; i++) {
13912                if (intent.filterEquals(list.get(i))) {
13913                    // This sticky already exists, replace it.
13914                    list.set(i, new Intent(intent));
13915                    break;
13916                }
13917            }
13918            if (i >= N) {
13919                list.add(new Intent(intent));
13920            }
13921        }
13922
13923        int[] users;
13924        if (userId == UserHandle.USER_ALL) {
13925            // Caller wants broadcast to go to all started users.
13926            users = mStartedUserArray;
13927        } else {
13928            // Caller wants broadcast to go to one specific user.
13929            users = new int[] {userId};
13930        }
13931
13932        // Figure out who all will receive this broadcast.
13933        List receivers = null;
13934        List<BroadcastFilter> registeredReceivers = null;
13935        // Need to resolve the intent to interested receivers...
13936        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13937                 == 0) {
13938            receivers = collectReceiverComponents(intent, resolvedType, users);
13939        }
13940        if (intent.getComponent() == null) {
13941            registeredReceivers = mReceiverResolver.queryIntent(intent,
13942                    resolvedType, false, userId);
13943        }
13944
13945        final boolean replacePending =
13946                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13947
13948        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13949                + " replacePending=" + replacePending);
13950
13951        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13952        if (!ordered && NR > 0) {
13953            // If we are not serializing this broadcast, then send the
13954            // registered receivers separately so they don't wait for the
13955            // components to be launched.
13956            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13957            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13958                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13959                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13960                    ordered, sticky, false, userId);
13961            if (DEBUG_BROADCAST) Slog.v(
13962                    TAG, "Enqueueing parallel broadcast " + r);
13963            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13964            if (!replaced) {
13965                queue.enqueueParallelBroadcastLocked(r);
13966                queue.scheduleBroadcastsLocked();
13967            }
13968            registeredReceivers = null;
13969            NR = 0;
13970        }
13971
13972        // Merge into one list.
13973        int ir = 0;
13974        if (receivers != null) {
13975            // A special case for PACKAGE_ADDED: do not allow the package
13976            // being added to see this broadcast.  This prevents them from
13977            // using this as a back door to get run as soon as they are
13978            // installed.  Maybe in the future we want to have a special install
13979            // broadcast or such for apps, but we'd like to deliberately make
13980            // this decision.
13981            String skipPackages[] = null;
13982            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13983                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13984                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13985                Uri data = intent.getData();
13986                if (data != null) {
13987                    String pkgName = data.getSchemeSpecificPart();
13988                    if (pkgName != null) {
13989                        skipPackages = new String[] { pkgName };
13990                    }
13991                }
13992            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13993                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13994            }
13995            if (skipPackages != null && (skipPackages.length > 0)) {
13996                for (String skipPackage : skipPackages) {
13997                    if (skipPackage != null) {
13998                        int NT = receivers.size();
13999                        for (int it=0; it<NT; it++) {
14000                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14001                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14002                                receivers.remove(it);
14003                                it--;
14004                                NT--;
14005                            }
14006                        }
14007                    }
14008                }
14009            }
14010
14011            int NT = receivers != null ? receivers.size() : 0;
14012            int it = 0;
14013            ResolveInfo curt = null;
14014            BroadcastFilter curr = null;
14015            while (it < NT && ir < NR) {
14016                if (curt == null) {
14017                    curt = (ResolveInfo)receivers.get(it);
14018                }
14019                if (curr == null) {
14020                    curr = registeredReceivers.get(ir);
14021                }
14022                if (curr.getPriority() >= curt.priority) {
14023                    // Insert this broadcast record into the final list.
14024                    receivers.add(it, curr);
14025                    ir++;
14026                    curr = null;
14027                    it++;
14028                    NT++;
14029                } else {
14030                    // Skip to the next ResolveInfo in the final list.
14031                    it++;
14032                    curt = null;
14033                }
14034            }
14035        }
14036        while (ir < NR) {
14037            if (receivers == null) {
14038                receivers = new ArrayList();
14039            }
14040            receivers.add(registeredReceivers.get(ir));
14041            ir++;
14042        }
14043
14044        if ((receivers != null && receivers.size() > 0)
14045                || resultTo != null) {
14046            BroadcastQueue queue = broadcastQueueForIntent(intent);
14047            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14048                    callerPackage, callingPid, callingUid, resolvedType,
14049                    requiredPermission, appOp, receivers, resultTo, resultCode,
14050                    resultData, map, ordered, sticky, false, userId);
14051            if (DEBUG_BROADCAST) Slog.v(
14052                    TAG, "Enqueueing ordered broadcast " + r
14053                    + ": prev had " + queue.mOrderedBroadcasts.size());
14054            if (DEBUG_BROADCAST) {
14055                int seq = r.intent.getIntExtra("seq", -1);
14056                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14057            }
14058            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14059            if (!replaced) {
14060                queue.enqueueOrderedBroadcastLocked(r);
14061                queue.scheduleBroadcastsLocked();
14062            }
14063        }
14064
14065        return ActivityManager.BROADCAST_SUCCESS;
14066    }
14067
14068    final Intent verifyBroadcastLocked(Intent intent) {
14069        // Refuse possible leaked file descriptors
14070        if (intent != null && intent.hasFileDescriptors() == true) {
14071            throw new IllegalArgumentException("File descriptors passed in Intent");
14072        }
14073
14074        int flags = intent.getFlags();
14075
14076        if (!mProcessesReady) {
14077            // if the caller really truly claims to know what they're doing, go
14078            // ahead and allow the broadcast without launching any receivers
14079            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14080                intent = new Intent(intent);
14081                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14082            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14083                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14084                        + " before boot completion");
14085                throw new IllegalStateException("Cannot broadcast before boot completed");
14086            }
14087        }
14088
14089        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14090            throw new IllegalArgumentException(
14091                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14092        }
14093
14094        return intent;
14095    }
14096
14097    public final int broadcastIntent(IApplicationThread caller,
14098            Intent intent, String resolvedType, IIntentReceiver resultTo,
14099            int resultCode, String resultData, Bundle map,
14100            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14101        enforceNotIsolatedCaller("broadcastIntent");
14102        synchronized(this) {
14103            intent = verifyBroadcastLocked(intent);
14104
14105            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14106            final int callingPid = Binder.getCallingPid();
14107            final int callingUid = Binder.getCallingUid();
14108            final long origId = Binder.clearCallingIdentity();
14109            int res = broadcastIntentLocked(callerApp,
14110                    callerApp != null ? callerApp.info.packageName : null,
14111                    intent, resolvedType, resultTo,
14112                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14113                    callingPid, callingUid, userId);
14114            Binder.restoreCallingIdentity(origId);
14115            return res;
14116        }
14117    }
14118
14119    int broadcastIntentInPackage(String packageName, int uid,
14120            Intent intent, String resolvedType, IIntentReceiver resultTo,
14121            int resultCode, String resultData, Bundle map,
14122            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14123        synchronized(this) {
14124            intent = verifyBroadcastLocked(intent);
14125
14126            final long origId = Binder.clearCallingIdentity();
14127            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14128                    resultTo, resultCode, resultData, map, requiredPermission,
14129                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14130            Binder.restoreCallingIdentity(origId);
14131            return res;
14132        }
14133    }
14134
14135    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14136        // Refuse possible leaked file descriptors
14137        if (intent != null && intent.hasFileDescriptors() == true) {
14138            throw new IllegalArgumentException("File descriptors passed in Intent");
14139        }
14140
14141        userId = handleIncomingUser(Binder.getCallingPid(),
14142                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14143
14144        synchronized(this) {
14145            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14146                    != PackageManager.PERMISSION_GRANTED) {
14147                String msg = "Permission Denial: unbroadcastIntent() from pid="
14148                        + Binder.getCallingPid()
14149                        + ", uid=" + Binder.getCallingUid()
14150                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14151                Slog.w(TAG, msg);
14152                throw new SecurityException(msg);
14153            }
14154            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14155            if (stickies != null) {
14156                ArrayList<Intent> list = stickies.get(intent.getAction());
14157                if (list != null) {
14158                    int N = list.size();
14159                    int i;
14160                    for (i=0; i<N; i++) {
14161                        if (intent.filterEquals(list.get(i))) {
14162                            list.remove(i);
14163                            break;
14164                        }
14165                    }
14166                    if (list.size() <= 0) {
14167                        stickies.remove(intent.getAction());
14168                    }
14169                }
14170                if (stickies.size() <= 0) {
14171                    mStickyBroadcasts.remove(userId);
14172                }
14173            }
14174        }
14175    }
14176
14177    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14178            String resultData, Bundle resultExtras, boolean resultAbort) {
14179        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14180        if (r == null) {
14181            Slog.w(TAG, "finishReceiver called but not found on queue");
14182            return false;
14183        }
14184
14185        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14186    }
14187
14188    void backgroundServicesFinishedLocked(int userId) {
14189        for (BroadcastQueue queue : mBroadcastQueues) {
14190            queue.backgroundServicesFinishedLocked(userId);
14191        }
14192    }
14193
14194    public void finishReceiver(IBinder who, int resultCode, String resultData,
14195            Bundle resultExtras, boolean resultAbort) {
14196        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14197
14198        // Refuse possible leaked file descriptors
14199        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14200            throw new IllegalArgumentException("File descriptors passed in Bundle");
14201        }
14202
14203        final long origId = Binder.clearCallingIdentity();
14204        try {
14205            boolean doNext = false;
14206            BroadcastRecord r;
14207
14208            synchronized(this) {
14209                r = broadcastRecordForReceiverLocked(who);
14210                if (r != null) {
14211                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14212                        resultData, resultExtras, resultAbort, true);
14213                }
14214            }
14215
14216            if (doNext) {
14217                r.queue.processNextBroadcast(false);
14218            }
14219            trimApplications();
14220        } finally {
14221            Binder.restoreCallingIdentity(origId);
14222        }
14223    }
14224
14225    // =========================================================
14226    // INSTRUMENTATION
14227    // =========================================================
14228
14229    public boolean startInstrumentation(ComponentName className,
14230            String profileFile, int flags, Bundle arguments,
14231            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14232            int userId) {
14233        enforceNotIsolatedCaller("startInstrumentation");
14234        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14235                userId, false, true, "startInstrumentation", null);
14236        // Refuse possible leaked file descriptors
14237        if (arguments != null && arguments.hasFileDescriptors()) {
14238            throw new IllegalArgumentException("File descriptors passed in Bundle");
14239        }
14240
14241        synchronized(this) {
14242            InstrumentationInfo ii = null;
14243            ApplicationInfo ai = null;
14244            try {
14245                ii = mContext.getPackageManager().getInstrumentationInfo(
14246                    className, STOCK_PM_FLAGS);
14247                ai = AppGlobals.getPackageManager().getApplicationInfo(
14248                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14249            } catch (PackageManager.NameNotFoundException e) {
14250            } catch (RemoteException e) {
14251            }
14252            if (ii == null) {
14253                reportStartInstrumentationFailure(watcher, className,
14254                        "Unable to find instrumentation info for: " + className);
14255                return false;
14256            }
14257            if (ai == null) {
14258                reportStartInstrumentationFailure(watcher, className,
14259                        "Unable to find instrumentation target package: " + ii.targetPackage);
14260                return false;
14261            }
14262
14263            int match = mContext.getPackageManager().checkSignatures(
14264                    ii.targetPackage, ii.packageName);
14265            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14266                String msg = "Permission Denial: starting instrumentation "
14267                        + className + " from pid="
14268                        + Binder.getCallingPid()
14269                        + ", uid=" + Binder.getCallingPid()
14270                        + " not allowed because package " + ii.packageName
14271                        + " does not have a signature matching the target "
14272                        + ii.targetPackage;
14273                reportStartInstrumentationFailure(watcher, className, msg);
14274                throw new SecurityException(msg);
14275            }
14276
14277            final long origId = Binder.clearCallingIdentity();
14278            // Instrumentation can kill and relaunch even persistent processes
14279            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14280                    "start instr");
14281            ProcessRecord app = addAppLocked(ai, false);
14282            app.instrumentationClass = className;
14283            app.instrumentationInfo = ai;
14284            app.instrumentationProfileFile = profileFile;
14285            app.instrumentationArguments = arguments;
14286            app.instrumentationWatcher = watcher;
14287            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14288            app.instrumentationResultClass = className;
14289            Binder.restoreCallingIdentity(origId);
14290        }
14291
14292        return true;
14293    }
14294
14295    /**
14296     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14297     * error to the logs, but if somebody is watching, send the report there too.  This enables
14298     * the "am" command to report errors with more information.
14299     *
14300     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14301     * @param cn The component name of the instrumentation.
14302     * @param report The error report.
14303     */
14304    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14305            ComponentName cn, String report) {
14306        Slog.w(TAG, report);
14307        try {
14308            if (watcher != null) {
14309                Bundle results = new Bundle();
14310                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14311                results.putString("Error", report);
14312                watcher.instrumentationStatus(cn, -1, results);
14313            }
14314        } catch (RemoteException e) {
14315            Slog.w(TAG, e);
14316        }
14317    }
14318
14319    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14320        if (app.instrumentationWatcher != null) {
14321            try {
14322                // NOTE:  IInstrumentationWatcher *must* be oneway here
14323                app.instrumentationWatcher.instrumentationFinished(
14324                    app.instrumentationClass,
14325                    resultCode,
14326                    results);
14327            } catch (RemoteException e) {
14328            }
14329        }
14330        if (app.instrumentationUiAutomationConnection != null) {
14331            try {
14332                app.instrumentationUiAutomationConnection.shutdown();
14333            } catch (RemoteException re) {
14334                /* ignore */
14335            }
14336            // Only a UiAutomation can set this flag and now that
14337            // it is finished we make sure it is reset to its default.
14338            mUserIsMonkey = false;
14339        }
14340        app.instrumentationWatcher = null;
14341        app.instrumentationUiAutomationConnection = null;
14342        app.instrumentationClass = null;
14343        app.instrumentationInfo = null;
14344        app.instrumentationProfileFile = null;
14345        app.instrumentationArguments = null;
14346
14347        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14348                "finished inst");
14349    }
14350
14351    public void finishInstrumentation(IApplicationThread target,
14352            int resultCode, Bundle results) {
14353        int userId = UserHandle.getCallingUserId();
14354        // Refuse possible leaked file descriptors
14355        if (results != null && results.hasFileDescriptors()) {
14356            throw new IllegalArgumentException("File descriptors passed in Intent");
14357        }
14358
14359        synchronized(this) {
14360            ProcessRecord app = getRecordForAppLocked(target);
14361            if (app == null) {
14362                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14363                return;
14364            }
14365            final long origId = Binder.clearCallingIdentity();
14366            finishInstrumentationLocked(app, resultCode, results);
14367            Binder.restoreCallingIdentity(origId);
14368        }
14369    }
14370
14371    // =========================================================
14372    // CONFIGURATION
14373    // =========================================================
14374
14375    public ConfigurationInfo getDeviceConfigurationInfo() {
14376        ConfigurationInfo config = new ConfigurationInfo();
14377        synchronized (this) {
14378            config.reqTouchScreen = mConfiguration.touchscreen;
14379            config.reqKeyboardType = mConfiguration.keyboard;
14380            config.reqNavigation = mConfiguration.navigation;
14381            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14382                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14383                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14384            }
14385            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14386                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14387                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14388            }
14389            config.reqGlEsVersion = GL_ES_VERSION;
14390        }
14391        return config;
14392    }
14393
14394    ActivityStack getFocusedStack() {
14395        return mStackSupervisor.getFocusedStack();
14396    }
14397
14398    public Configuration getConfiguration() {
14399        Configuration ci;
14400        synchronized(this) {
14401            ci = new Configuration(mConfiguration);
14402        }
14403        return ci;
14404    }
14405
14406    public void updatePersistentConfiguration(Configuration values) {
14407        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14408                "updateConfiguration()");
14409        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14410                "updateConfiguration()");
14411        if (values == null) {
14412            throw new NullPointerException("Configuration must not be null");
14413        }
14414
14415        synchronized(this) {
14416            final long origId = Binder.clearCallingIdentity();
14417            updateConfigurationLocked(values, null, true, false);
14418            Binder.restoreCallingIdentity(origId);
14419        }
14420    }
14421
14422    public void updateConfiguration(Configuration values) {
14423        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14424                "updateConfiguration()");
14425
14426        synchronized(this) {
14427            if (values == null && mWindowManager != null) {
14428                // sentinel: fetch the current configuration from the window manager
14429                values = mWindowManager.computeNewConfiguration();
14430            }
14431
14432            if (mWindowManager != null) {
14433                mProcessList.applyDisplaySize(mWindowManager);
14434            }
14435
14436            final long origId = Binder.clearCallingIdentity();
14437            if (values != null) {
14438                Settings.System.clearConfiguration(values);
14439            }
14440            updateConfigurationLocked(values, null, false, false);
14441            Binder.restoreCallingIdentity(origId);
14442        }
14443    }
14444
14445    /**
14446     * Do either or both things: (1) change the current configuration, and (2)
14447     * make sure the given activity is running with the (now) current
14448     * configuration.  Returns true if the activity has been left running, or
14449     * false if <var>starting</var> is being destroyed to match the new
14450     * configuration.
14451     * @param persistent TODO
14452     */
14453    boolean updateConfigurationLocked(Configuration values,
14454            ActivityRecord starting, boolean persistent, boolean initLocale) {
14455        int changes = 0;
14456
14457        if (values != null) {
14458            Configuration newConfig = new Configuration(mConfiguration);
14459            changes = newConfig.updateFrom(values);
14460            if (changes != 0) {
14461                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14462                    Slog.i(TAG, "Updating configuration to: " + values);
14463                }
14464
14465                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14466
14467                if (values.locale != null && !initLocale) {
14468                    saveLocaleLocked(values.locale,
14469                                     !values.locale.equals(mConfiguration.locale),
14470                                     values.userSetLocale);
14471                }
14472
14473                mConfigurationSeq++;
14474                if (mConfigurationSeq <= 0) {
14475                    mConfigurationSeq = 1;
14476                }
14477                newConfig.seq = mConfigurationSeq;
14478                mConfiguration = newConfig;
14479                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14480                mUsageStatsService.noteStartConfig(newConfig);
14481
14482                final Configuration configCopy = new Configuration(mConfiguration);
14483
14484                // TODO: If our config changes, should we auto dismiss any currently
14485                // showing dialogs?
14486                mShowDialogs = shouldShowDialogs(newConfig);
14487
14488                AttributeCache ac = AttributeCache.instance();
14489                if (ac != null) {
14490                    ac.updateConfiguration(configCopy);
14491                }
14492
14493                // Make sure all resources in our process are updated
14494                // right now, so that anyone who is going to retrieve
14495                // resource values after we return will be sure to get
14496                // the new ones.  This is especially important during
14497                // boot, where the first config change needs to guarantee
14498                // all resources have that config before following boot
14499                // code is executed.
14500                mSystemThread.applyConfigurationToResources(configCopy);
14501
14502                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14503                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14504                    msg.obj = new Configuration(configCopy);
14505                    mHandler.sendMessage(msg);
14506                }
14507
14508                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14509                    ProcessRecord app = mLruProcesses.get(i);
14510                    try {
14511                        if (app.thread != null) {
14512                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14513                                    + app.processName + " new config " + mConfiguration);
14514                            app.thread.scheduleConfigurationChanged(configCopy);
14515                        }
14516                    } catch (Exception e) {
14517                    }
14518                }
14519                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14520                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14521                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14522                        | Intent.FLAG_RECEIVER_FOREGROUND);
14523                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14524                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14525                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14526                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14527                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14528                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14529                    broadcastIntentLocked(null, null, intent,
14530                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14531                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14532                }
14533            }
14534        }
14535
14536        boolean kept = true;
14537        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14538        // mainStack is null during startup.
14539        if (mainStack != null) {
14540            if (changes != 0 && starting == null) {
14541                // If the configuration changed, and the caller is not already
14542                // in the process of starting an activity, then find the top
14543                // activity to check if its configuration needs to change.
14544                starting = mainStack.topRunningActivityLocked(null);
14545            }
14546
14547            if (starting != null) {
14548                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14549                // And we need to make sure at this point that all other activities
14550                // are made visible with the correct configuration.
14551                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14552            }
14553        }
14554
14555        if (values != null && mWindowManager != null) {
14556            mWindowManager.setNewConfiguration(mConfiguration);
14557        }
14558
14559        return kept;
14560    }
14561
14562    /**
14563     * Decide based on the configuration whether we should shouw the ANR,
14564     * crash, etc dialogs.  The idea is that if there is no affordnace to
14565     * press the on-screen buttons, we shouldn't show the dialog.
14566     *
14567     * A thought: SystemUI might also want to get told about this, the Power
14568     * dialog / global actions also might want different behaviors.
14569     */
14570    private static final boolean shouldShowDialogs(Configuration config) {
14571        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14572                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14573    }
14574
14575    /**
14576     * Save the locale.  You must be inside a synchronized (this) block.
14577     */
14578    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14579        if(isDiff) {
14580            SystemProperties.set("user.language", l.getLanguage());
14581            SystemProperties.set("user.region", l.getCountry());
14582        }
14583
14584        if(isPersist) {
14585            SystemProperties.set("persist.sys.language", l.getLanguage());
14586            SystemProperties.set("persist.sys.country", l.getCountry());
14587            SystemProperties.set("persist.sys.localevar", l.getVariant());
14588        }
14589    }
14590
14591    @Override
14592    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14593        ActivityRecord srec = ActivityRecord.forToken(token);
14594        return srec != null && srec.task.affinity != null &&
14595                srec.task.affinity.equals(destAffinity);
14596    }
14597
14598    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14599            Intent resultData) {
14600
14601        synchronized (this) {
14602            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14603            if (stack != null) {
14604                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14605            }
14606            return false;
14607        }
14608    }
14609
14610    public int getLaunchedFromUid(IBinder activityToken) {
14611        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14612        if (srec == null) {
14613            return -1;
14614        }
14615        return srec.launchedFromUid;
14616    }
14617
14618    public String getLaunchedFromPackage(IBinder activityToken) {
14619        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14620        if (srec == null) {
14621            return null;
14622        }
14623        return srec.launchedFromPackage;
14624    }
14625
14626    // =========================================================
14627    // LIFETIME MANAGEMENT
14628    // =========================================================
14629
14630    // Returns which broadcast queue the app is the current [or imminent] receiver
14631    // on, or 'null' if the app is not an active broadcast recipient.
14632    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14633        BroadcastRecord r = app.curReceiver;
14634        if (r != null) {
14635            return r.queue;
14636        }
14637
14638        // It's not the current receiver, but it might be starting up to become one
14639        synchronized (this) {
14640            for (BroadcastQueue queue : mBroadcastQueues) {
14641                r = queue.mPendingBroadcast;
14642                if (r != null && r.curApp == app) {
14643                    // found it; report which queue it's in
14644                    return queue;
14645                }
14646            }
14647        }
14648
14649        return null;
14650    }
14651
14652    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14653            boolean doingAll, long now) {
14654        if (mAdjSeq == app.adjSeq) {
14655            // This adjustment has already been computed.
14656            return app.curRawAdj;
14657        }
14658
14659        if (app.thread == null) {
14660            app.adjSeq = mAdjSeq;
14661            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14662            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14663            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14664        }
14665
14666        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14667        app.adjSource = null;
14668        app.adjTarget = null;
14669        app.empty = false;
14670        app.cached = false;
14671
14672        final int activitiesSize = app.activities.size();
14673
14674        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14675            // The max adjustment doesn't allow this app to be anything
14676            // below foreground, so it is not worth doing work for it.
14677            app.adjType = "fixed";
14678            app.adjSeq = mAdjSeq;
14679            app.curRawAdj = app.maxAdj;
14680            app.foregroundActivities = false;
14681            app.keeping = true;
14682            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14683            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14684            // System processes can do UI, and when they do we want to have
14685            // them trim their memory after the user leaves the UI.  To
14686            // facilitate this, here we need to determine whether or not it
14687            // is currently showing UI.
14688            app.systemNoUi = true;
14689            if (app == TOP_APP) {
14690                app.systemNoUi = false;
14691            } else if (activitiesSize > 0) {
14692                for (int j = 0; j < activitiesSize; j++) {
14693                    final ActivityRecord r = app.activities.get(j);
14694                    if (r.visible) {
14695                        app.systemNoUi = false;
14696                    }
14697                }
14698            }
14699            if (!app.systemNoUi) {
14700                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14701            }
14702            return (app.curAdj=app.maxAdj);
14703        }
14704
14705        app.keeping = false;
14706        app.systemNoUi = false;
14707
14708        // Determine the importance of the process, starting with most
14709        // important to least, and assign an appropriate OOM adjustment.
14710        int adj;
14711        int schedGroup;
14712        int procState;
14713        boolean foregroundActivities = false;
14714        boolean interesting = false;
14715        BroadcastQueue queue;
14716        if (app == TOP_APP) {
14717            // The last app on the list is the foreground app.
14718            adj = ProcessList.FOREGROUND_APP_ADJ;
14719            schedGroup = Process.THREAD_GROUP_DEFAULT;
14720            app.adjType = "top-activity";
14721            foregroundActivities = true;
14722            interesting = true;
14723            procState = ActivityManager.PROCESS_STATE_TOP;
14724        } else if (app.instrumentationClass != null) {
14725            // Don't want to kill running instrumentation.
14726            adj = ProcessList.FOREGROUND_APP_ADJ;
14727            schedGroup = Process.THREAD_GROUP_DEFAULT;
14728            app.adjType = "instrumentation";
14729            interesting = true;
14730            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14731        } else if ((queue = isReceivingBroadcast(app)) != null) {
14732            // An app that is currently receiving a broadcast also
14733            // counts as being in the foreground for OOM killer purposes.
14734            // It's placed in a sched group based on the nature of the
14735            // broadcast as reflected by which queue it's active in.
14736            adj = ProcessList.FOREGROUND_APP_ADJ;
14737            schedGroup = (queue == mFgBroadcastQueue)
14738                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14739            app.adjType = "broadcast";
14740            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14741        } else if (app.executingServices.size() > 0) {
14742            // An app that is currently executing a service callback also
14743            // counts as being in the foreground.
14744            adj = ProcessList.FOREGROUND_APP_ADJ;
14745            schedGroup = app.execServicesFg ?
14746                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14747            app.adjType = "exec-service";
14748            procState = ActivityManager.PROCESS_STATE_SERVICE;
14749            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14750        } else {
14751            // As far as we know the process is empty.  We may change our mind later.
14752            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14753            // At this point we don't actually know the adjustment.  Use the cached adj
14754            // value that the caller wants us to.
14755            adj = cachedAdj;
14756            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14757            app.cached = true;
14758            app.empty = true;
14759            app.adjType = "cch-empty";
14760        }
14761
14762        // Examine all activities if not already foreground.
14763        if (!foregroundActivities && activitiesSize > 0) {
14764            for (int j = 0; j < activitiesSize; j++) {
14765                final ActivityRecord r = app.activities.get(j);
14766                if (r.app != app) {
14767                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14768                            + app + "?!?");
14769                    continue;
14770                }
14771                if (r.visible) {
14772                    // App has a visible activity; only upgrade adjustment.
14773                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14774                        adj = ProcessList.VISIBLE_APP_ADJ;
14775                        app.adjType = "visible";
14776                    }
14777                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14778                        procState = ActivityManager.PROCESS_STATE_TOP;
14779                    }
14780                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14781                    app.cached = false;
14782                    app.empty = false;
14783                    foregroundActivities = true;
14784                    break;
14785                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14786                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14787                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14788                        app.adjType = "pausing";
14789                    }
14790                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14791                        procState = ActivityManager.PROCESS_STATE_TOP;
14792                    }
14793                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14794                    app.cached = false;
14795                    app.empty = false;
14796                    foregroundActivities = true;
14797                } else if (r.state == ActivityState.STOPPING) {
14798                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14799                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14800                        app.adjType = "stopping";
14801                    }
14802                    // For the process state, we will at this point consider the
14803                    // process to be cached.  It will be cached either as an activity
14804                    // or empty depending on whether the activity is finishing.  We do
14805                    // this so that we can treat the process as cached for purposes of
14806                    // memory trimming (determing current memory level, trim command to
14807                    // send to process) since there can be an arbitrary number of stopping
14808                    // processes and they should soon all go into the cached state.
14809                    if (!r.finishing) {
14810                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14811                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14812                        }
14813                    }
14814                    app.cached = false;
14815                    app.empty = false;
14816                    foregroundActivities = true;
14817                } else {
14818                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14819                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14820                        app.adjType = "cch-act";
14821                    }
14822                }
14823            }
14824        }
14825
14826        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14827            if (app.foregroundServices) {
14828                // The user is aware of this app, so make it visible.
14829                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14830                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14831                app.cached = false;
14832                app.adjType = "fg-service";
14833                schedGroup = Process.THREAD_GROUP_DEFAULT;
14834            } else if (app.forcingToForeground != null) {
14835                // The user is aware of this app, so make it visible.
14836                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14837                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14838                app.cached = false;
14839                app.adjType = "force-fg";
14840                app.adjSource = app.forcingToForeground;
14841                schedGroup = Process.THREAD_GROUP_DEFAULT;
14842            }
14843        }
14844
14845        if (app.foregroundServices) {
14846            interesting = true;
14847        }
14848
14849        if (app == mHeavyWeightProcess) {
14850            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14851                // We don't want to kill the current heavy-weight process.
14852                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14853                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14854                app.cached = false;
14855                app.adjType = "heavy";
14856            }
14857            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14858                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14859            }
14860        }
14861
14862        if (app == mHomeProcess) {
14863            if (adj > ProcessList.HOME_APP_ADJ) {
14864                // This process is hosting what we currently consider to be the
14865                // home app, so we don't want to let it go into the background.
14866                adj = ProcessList.HOME_APP_ADJ;
14867                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14868                app.cached = false;
14869                app.adjType = "home";
14870            }
14871            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14872                procState = ActivityManager.PROCESS_STATE_HOME;
14873            }
14874        }
14875
14876        if (app == mPreviousProcess && app.activities.size() > 0) {
14877            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14878                // This was the previous process that showed UI to the user.
14879                // We want to try to keep it around more aggressively, to give
14880                // a good experience around switching between two apps.
14881                adj = ProcessList.PREVIOUS_APP_ADJ;
14882                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14883                app.cached = false;
14884                app.adjType = "previous";
14885            }
14886            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14887                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14888            }
14889        }
14890
14891        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14892                + " reason=" + app.adjType);
14893
14894        // By default, we use the computed adjustment.  It may be changed if
14895        // there are applications dependent on our services or providers, but
14896        // this gives us a baseline and makes sure we don't get into an
14897        // infinite recursion.
14898        app.adjSeq = mAdjSeq;
14899        app.curRawAdj = adj;
14900        app.hasStartedServices = false;
14901
14902        if (mBackupTarget != null && app == mBackupTarget.app) {
14903            // If possible we want to avoid killing apps while they're being backed up
14904            if (adj > ProcessList.BACKUP_APP_ADJ) {
14905                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14906                adj = ProcessList.BACKUP_APP_ADJ;
14907                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14908                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14909                }
14910                app.adjType = "backup";
14911                app.cached = false;
14912            }
14913            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14914                procState = ActivityManager.PROCESS_STATE_BACKUP;
14915            }
14916        }
14917
14918        boolean mayBeTop = false;
14919
14920        for (int is = app.services.size()-1;
14921                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14922                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14923                        || procState > ActivityManager.PROCESS_STATE_TOP);
14924                is--) {
14925            ServiceRecord s = app.services.valueAt(is);
14926            if (s.startRequested) {
14927                app.hasStartedServices = true;
14928                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14929                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14930                }
14931                if (app.hasShownUi && app != mHomeProcess) {
14932                    // If this process has shown some UI, let it immediately
14933                    // go to the LRU list because it may be pretty heavy with
14934                    // UI stuff.  We'll tag it with a label just to help
14935                    // debug and understand what is going on.
14936                    if (adj > ProcessList.SERVICE_ADJ) {
14937                        app.adjType = "cch-started-ui-services";
14938                    }
14939                } else {
14940                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14941                        // This service has seen some activity within
14942                        // recent memory, so we will keep its process ahead
14943                        // of the background processes.
14944                        if (adj > ProcessList.SERVICE_ADJ) {
14945                            adj = ProcessList.SERVICE_ADJ;
14946                            app.adjType = "started-services";
14947                            app.cached = false;
14948                        }
14949                    }
14950                    // If we have let the service slide into the background
14951                    // state, still have some text describing what it is doing
14952                    // even though the service no longer has an impact.
14953                    if (adj > ProcessList.SERVICE_ADJ) {
14954                        app.adjType = "cch-started-services";
14955                    }
14956                }
14957                // Don't kill this process because it is doing work; it
14958                // has said it is doing work.
14959                app.keeping = true;
14960            }
14961            for (int conni = s.connections.size()-1;
14962                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14963                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14964                            || procState > ActivityManager.PROCESS_STATE_TOP);
14965                    conni--) {
14966                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14967                for (int i = 0;
14968                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14969                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14970                                || procState > ActivityManager.PROCESS_STATE_TOP);
14971                        i++) {
14972                    // XXX should compute this based on the max of
14973                    // all connected clients.
14974                    ConnectionRecord cr = clist.get(i);
14975                    if (cr.binding.client == app) {
14976                        // Binding to ourself is not interesting.
14977                        continue;
14978                    }
14979                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14980                        ProcessRecord client = cr.binding.client;
14981                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14982                                TOP_APP, doingAll, now);
14983                        int clientProcState = client.curProcState;
14984                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14985                            // If the other app is cached for any reason, for purposes here
14986                            // we are going to consider it empty.  The specific cached state
14987                            // doesn't propagate except under certain conditions.
14988                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14989                        }
14990                        String adjType = null;
14991                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14992                            // Not doing bind OOM management, so treat
14993                            // this guy more like a started service.
14994                            if (app.hasShownUi && app != mHomeProcess) {
14995                                // If this process has shown some UI, let it immediately
14996                                // go to the LRU list because it may be pretty heavy with
14997                                // UI stuff.  We'll tag it with a label just to help
14998                                // debug and understand what is going on.
14999                                if (adj > clientAdj) {
15000                                    adjType = "cch-bound-ui-services";
15001                                }
15002                                app.cached = false;
15003                                clientAdj = adj;
15004                                clientProcState = procState;
15005                            } else {
15006                                if (now >= (s.lastActivity
15007                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15008                                    // This service has not seen activity within
15009                                    // recent memory, so allow it to drop to the
15010                                    // LRU list if there is no other reason to keep
15011                                    // it around.  We'll also tag it with a label just
15012                                    // to help debug and undertand what is going on.
15013                                    if (adj > clientAdj) {
15014                                        adjType = "cch-bound-services";
15015                                    }
15016                                    clientAdj = adj;
15017                                }
15018                            }
15019                        }
15020                        if (adj > clientAdj) {
15021                            // If this process has recently shown UI, and
15022                            // the process that is binding to it is less
15023                            // important than being visible, then we don't
15024                            // care about the binding as much as we care
15025                            // about letting this process get into the LRU
15026                            // list to be killed and restarted if needed for
15027                            // memory.
15028                            if (app.hasShownUi && app != mHomeProcess
15029                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15030                                adjType = "cch-bound-ui-services";
15031                            } else {
15032                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15033                                        |Context.BIND_IMPORTANT)) != 0) {
15034                                    adj = clientAdj;
15035                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15036                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15037                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15038                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15039                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15040                                    adj = clientAdj;
15041                                } else {
15042                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15043                                        adj = ProcessList.VISIBLE_APP_ADJ;
15044                                    }
15045                                }
15046                                if (!client.cached) {
15047                                    app.cached = false;
15048                                }
15049                                if (client.keeping) {
15050                                    app.keeping = true;
15051                                }
15052                                adjType = "service";
15053                            }
15054                        }
15055                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15056                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15057                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15058                            }
15059                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15060                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15061                                    // Special handling of clients who are in the top state.
15062                                    // We *may* want to consider this process to be in the
15063                                    // top state as well, but only if there is not another
15064                                    // reason for it to be running.  Being on the top is a
15065                                    // special state, meaning you are specifically running
15066                                    // for the current top app.  If the process is already
15067                                    // running in the background for some other reason, it
15068                                    // is more important to continue considering it to be
15069                                    // in the background state.
15070                                    mayBeTop = true;
15071                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15072                                } else {
15073                                    // Special handling for above-top states (persistent
15074                                    // processes).  These should not bring the current process
15075                                    // into the top state, since they are not on top.  Instead
15076                                    // give them the best state after that.
15077                                    clientProcState =
15078                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15079                                }
15080                            }
15081                        } else {
15082                            if (clientProcState <
15083                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15084                                clientProcState =
15085                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15086                            }
15087                        }
15088                        if (procState > clientProcState) {
15089                            procState = clientProcState;
15090                        }
15091                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15092                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15093                            app.pendingUiClean = true;
15094                        }
15095                        if (adjType != null) {
15096                            app.adjType = adjType;
15097                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15098                                    .REASON_SERVICE_IN_USE;
15099                            app.adjSource = cr.binding.client;
15100                            app.adjSourceOom = clientAdj;
15101                            app.adjTarget = s.name;
15102                        }
15103                    }
15104                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15105                        app.treatLikeActivity = true;
15106                    }
15107                    final ActivityRecord a = cr.activity;
15108                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15109                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15110                                (a.visible || a.state == ActivityState.RESUMED
15111                                 || a.state == ActivityState.PAUSING)) {
15112                            adj = ProcessList.FOREGROUND_APP_ADJ;
15113                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15114                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15115                            }
15116                            app.cached = false;
15117                            app.adjType = "service";
15118                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15119                                    .REASON_SERVICE_IN_USE;
15120                            app.adjSource = a;
15121                            app.adjSourceOom = adj;
15122                            app.adjTarget = s.name;
15123                        }
15124                    }
15125                }
15126            }
15127        }
15128
15129        for (int provi = app.pubProviders.size()-1;
15130                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15131                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15132                        || procState > ActivityManager.PROCESS_STATE_TOP);
15133                provi--) {
15134            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15135            for (int i = cpr.connections.size()-1;
15136                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15137                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15138                            || procState > ActivityManager.PROCESS_STATE_TOP);
15139                    i--) {
15140                ContentProviderConnection conn = cpr.connections.get(i);
15141                ProcessRecord client = conn.client;
15142                if (client == app) {
15143                    // Being our own client is not interesting.
15144                    continue;
15145                }
15146                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15147                int clientProcState = client.curProcState;
15148                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15149                    // If the other app is cached for any reason, for purposes here
15150                    // we are going to consider it empty.
15151                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15152                }
15153                if (adj > clientAdj) {
15154                    if (app.hasShownUi && app != mHomeProcess
15155                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15156                        app.adjType = "cch-ui-provider";
15157                    } else {
15158                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15159                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15160                        app.adjType = "provider";
15161                    }
15162                    app.cached &= client.cached;
15163                    app.keeping |= client.keeping;
15164                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15165                            .REASON_PROVIDER_IN_USE;
15166                    app.adjSource = client;
15167                    app.adjSourceOom = clientAdj;
15168                    app.adjTarget = cpr.name;
15169                }
15170                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15171                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15172                        // Special handling of clients who are in the top state.
15173                        // We *may* want to consider this process to be in the
15174                        // top state as well, but only if there is not another
15175                        // reason for it to be running.  Being on the top is a
15176                        // special state, meaning you are specifically running
15177                        // for the current top app.  If the process is already
15178                        // running in the background for some other reason, it
15179                        // is more important to continue considering it to be
15180                        // in the background state.
15181                        mayBeTop = true;
15182                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15183                    } else {
15184                        // Special handling for above-top states (persistent
15185                        // processes).  These should not bring the current process
15186                        // into the top state, since they are not on top.  Instead
15187                        // give them the best state after that.
15188                        clientProcState =
15189                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15190                    }
15191                }
15192                if (procState > clientProcState) {
15193                    procState = clientProcState;
15194                }
15195                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15196                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15197                }
15198            }
15199            // If the provider has external (non-framework) process
15200            // dependencies, ensure that its adjustment is at least
15201            // FOREGROUND_APP_ADJ.
15202            if (cpr.hasExternalProcessHandles()) {
15203                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15204                    adj = ProcessList.FOREGROUND_APP_ADJ;
15205                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15206                    app.cached = false;
15207                    app.keeping = true;
15208                    app.adjType = "provider";
15209                    app.adjTarget = cpr.name;
15210                }
15211                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15212                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15213                }
15214            }
15215        }
15216
15217        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15218            // A client of one of our services or providers is in the top state.  We
15219            // *may* want to be in the top state, but not if we are already running in
15220            // the background for some other reason.  For the decision here, we are going
15221            // to pick out a few specific states that we want to remain in when a client
15222            // is top (states that tend to be longer-term) and otherwise allow it to go
15223            // to the top state.
15224            switch (procState) {
15225                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15226                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15227                case ActivityManager.PROCESS_STATE_SERVICE:
15228                    // These all are longer-term states, so pull them up to the top
15229                    // of the background states, but not all the way to the top state.
15230                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15231                    break;
15232                default:
15233                    // Otherwise, top is a better choice, so take it.
15234                    procState = ActivityManager.PROCESS_STATE_TOP;
15235                    break;
15236            }
15237        }
15238
15239        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15240            if (app.hasClientActivities) {
15241                // This is a cached process, but with client activities.  Mark it so.
15242                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15243                app.adjType = "cch-client-act";
15244            } else if (app.treatLikeActivity) {
15245                // This is a cached process, but somebody wants us to treat it like it has
15246                // an activity, okay!
15247                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15248                app.adjType = "cch-as-act";
15249            }
15250        }
15251
15252        if (adj == ProcessList.SERVICE_ADJ) {
15253            if (doingAll) {
15254                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15255                mNewNumServiceProcs++;
15256                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15257                if (!app.serviceb) {
15258                    // This service isn't far enough down on the LRU list to
15259                    // normally be a B service, but if we are low on RAM and it
15260                    // is large we want to force it down since we would prefer to
15261                    // keep launcher over it.
15262                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15263                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15264                        app.serviceHighRam = true;
15265                        app.serviceb = true;
15266                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15267                    } else {
15268                        mNewNumAServiceProcs++;
15269                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15270                    }
15271                } else {
15272                    app.serviceHighRam = false;
15273                }
15274            }
15275            if (app.serviceb) {
15276                adj = ProcessList.SERVICE_B_ADJ;
15277            }
15278        }
15279
15280        app.curRawAdj = adj;
15281
15282        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15283        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15284        if (adj > app.maxAdj) {
15285            adj = app.maxAdj;
15286            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15287                schedGroup = Process.THREAD_GROUP_DEFAULT;
15288            }
15289        }
15290        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15291            app.keeping = true;
15292        }
15293
15294        // Do final modification to adj.  Everything we do between here and applying
15295        // the final setAdj must be done in this function, because we will also use
15296        // it when computing the final cached adj later.  Note that we don't need to
15297        // worry about this for max adj above, since max adj will always be used to
15298        // keep it out of the cached vaues.
15299        app.curAdj = app.modifyRawOomAdj(adj);
15300        app.curSchedGroup = schedGroup;
15301        app.curProcState = procState;
15302        app.foregroundActivities = foregroundActivities;
15303
15304        return app.curRawAdj;
15305    }
15306
15307    /**
15308     * Schedule PSS collection of a process.
15309     */
15310    void requestPssLocked(ProcessRecord proc, int procState) {
15311        if (mPendingPssProcesses.contains(proc)) {
15312            return;
15313        }
15314        if (mPendingPssProcesses.size() == 0) {
15315            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15316        }
15317        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15318        proc.pssProcState = procState;
15319        mPendingPssProcesses.add(proc);
15320    }
15321
15322    /**
15323     * Schedule PSS collection of all processes.
15324     */
15325    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15326        if (!always) {
15327            if (now < (mLastFullPssTime +
15328                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15329                return;
15330            }
15331        }
15332        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15333        mLastFullPssTime = now;
15334        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15335        mPendingPssProcesses.clear();
15336        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15337            ProcessRecord app = mLruProcesses.get(i);
15338            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15339                app.pssProcState = app.setProcState;
15340                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15341                        isSleeping(), now);
15342                mPendingPssProcesses.add(app);
15343            }
15344        }
15345        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15346    }
15347
15348    /**
15349     * Ask a given process to GC right now.
15350     */
15351    final void performAppGcLocked(ProcessRecord app) {
15352        try {
15353            app.lastRequestedGc = SystemClock.uptimeMillis();
15354            if (app.thread != null) {
15355                if (app.reportLowMemory) {
15356                    app.reportLowMemory = false;
15357                    app.thread.scheduleLowMemory();
15358                } else {
15359                    app.thread.processInBackground();
15360                }
15361            }
15362        } catch (Exception e) {
15363            // whatever.
15364        }
15365    }
15366
15367    /**
15368     * Returns true if things are idle enough to perform GCs.
15369     */
15370    private final boolean canGcNowLocked() {
15371        boolean processingBroadcasts = false;
15372        for (BroadcastQueue q : mBroadcastQueues) {
15373            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15374                processingBroadcasts = true;
15375            }
15376        }
15377        return !processingBroadcasts
15378                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15379    }
15380
15381    /**
15382     * Perform GCs on all processes that are waiting for it, but only
15383     * if things are idle.
15384     */
15385    final void performAppGcsLocked() {
15386        final int N = mProcessesToGc.size();
15387        if (N <= 0) {
15388            return;
15389        }
15390        if (canGcNowLocked()) {
15391            while (mProcessesToGc.size() > 0) {
15392                ProcessRecord proc = mProcessesToGc.remove(0);
15393                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15394                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15395                            <= SystemClock.uptimeMillis()) {
15396                        // To avoid spamming the system, we will GC processes one
15397                        // at a time, waiting a few seconds between each.
15398                        performAppGcLocked(proc);
15399                        scheduleAppGcsLocked();
15400                        return;
15401                    } else {
15402                        // It hasn't been long enough since we last GCed this
15403                        // process...  put it in the list to wait for its time.
15404                        addProcessToGcListLocked(proc);
15405                        break;
15406                    }
15407                }
15408            }
15409
15410            scheduleAppGcsLocked();
15411        }
15412    }
15413
15414    /**
15415     * If all looks good, perform GCs on all processes waiting for them.
15416     */
15417    final void performAppGcsIfAppropriateLocked() {
15418        if (canGcNowLocked()) {
15419            performAppGcsLocked();
15420            return;
15421        }
15422        // Still not idle, wait some more.
15423        scheduleAppGcsLocked();
15424    }
15425
15426    /**
15427     * Schedule the execution of all pending app GCs.
15428     */
15429    final void scheduleAppGcsLocked() {
15430        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15431
15432        if (mProcessesToGc.size() > 0) {
15433            // Schedule a GC for the time to the next process.
15434            ProcessRecord proc = mProcessesToGc.get(0);
15435            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15436
15437            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15438            long now = SystemClock.uptimeMillis();
15439            if (when < (now+GC_TIMEOUT)) {
15440                when = now + GC_TIMEOUT;
15441            }
15442            mHandler.sendMessageAtTime(msg, when);
15443        }
15444    }
15445
15446    /**
15447     * Add a process to the array of processes waiting to be GCed.  Keeps the
15448     * list in sorted order by the last GC time.  The process can't already be
15449     * on the list.
15450     */
15451    final void addProcessToGcListLocked(ProcessRecord proc) {
15452        boolean added = false;
15453        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15454            if (mProcessesToGc.get(i).lastRequestedGc <
15455                    proc.lastRequestedGc) {
15456                added = true;
15457                mProcessesToGc.add(i+1, proc);
15458                break;
15459            }
15460        }
15461        if (!added) {
15462            mProcessesToGc.add(0, proc);
15463        }
15464    }
15465
15466    /**
15467     * Set up to ask a process to GC itself.  This will either do it
15468     * immediately, or put it on the list of processes to gc the next
15469     * time things are idle.
15470     */
15471    final void scheduleAppGcLocked(ProcessRecord app) {
15472        long now = SystemClock.uptimeMillis();
15473        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15474            return;
15475        }
15476        if (!mProcessesToGc.contains(app)) {
15477            addProcessToGcListLocked(app);
15478            scheduleAppGcsLocked();
15479        }
15480    }
15481
15482    final void checkExcessivePowerUsageLocked(boolean doKills) {
15483        updateCpuStatsNow();
15484
15485        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15486        boolean doWakeKills = doKills;
15487        boolean doCpuKills = doKills;
15488        if (mLastPowerCheckRealtime == 0) {
15489            doWakeKills = false;
15490        }
15491        if (mLastPowerCheckUptime == 0) {
15492            doCpuKills = false;
15493        }
15494        if (stats.isScreenOn()) {
15495            doWakeKills = false;
15496        }
15497        final long curRealtime = SystemClock.elapsedRealtime();
15498        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15499        final long curUptime = SystemClock.uptimeMillis();
15500        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15501        mLastPowerCheckRealtime = curRealtime;
15502        mLastPowerCheckUptime = curUptime;
15503        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15504            doWakeKills = false;
15505        }
15506        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15507            doCpuKills = false;
15508        }
15509        int i = mLruProcesses.size();
15510        while (i > 0) {
15511            i--;
15512            ProcessRecord app = mLruProcesses.get(i);
15513            if (!app.keeping) {
15514                long wtime;
15515                synchronized (stats) {
15516                    wtime = stats.getProcessWakeTime(app.info.uid,
15517                            app.pid, curRealtime);
15518                }
15519                long wtimeUsed = wtime - app.lastWakeTime;
15520                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15521                if (DEBUG_POWER) {
15522                    StringBuilder sb = new StringBuilder(128);
15523                    sb.append("Wake for ");
15524                    app.toShortString(sb);
15525                    sb.append(": over ");
15526                    TimeUtils.formatDuration(realtimeSince, sb);
15527                    sb.append(" used ");
15528                    TimeUtils.formatDuration(wtimeUsed, sb);
15529                    sb.append(" (");
15530                    sb.append((wtimeUsed*100)/realtimeSince);
15531                    sb.append("%)");
15532                    Slog.i(TAG, sb.toString());
15533                    sb.setLength(0);
15534                    sb.append("CPU for ");
15535                    app.toShortString(sb);
15536                    sb.append(": over ");
15537                    TimeUtils.formatDuration(uptimeSince, sb);
15538                    sb.append(" used ");
15539                    TimeUtils.formatDuration(cputimeUsed, sb);
15540                    sb.append(" (");
15541                    sb.append((cputimeUsed*100)/uptimeSince);
15542                    sb.append("%)");
15543                    Slog.i(TAG, sb.toString());
15544                }
15545                // If a process has held a wake lock for more
15546                // than 50% of the time during this period,
15547                // that sounds bad.  Kill!
15548                if (doWakeKills && realtimeSince > 0
15549                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15550                    synchronized (stats) {
15551                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15552                                realtimeSince, wtimeUsed);
15553                    }
15554                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15555                            + " during " + realtimeSince);
15556                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15557                } else if (doCpuKills && uptimeSince > 0
15558                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15559                    synchronized (stats) {
15560                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15561                                uptimeSince, cputimeUsed);
15562                    }
15563                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15564                            + " during " + uptimeSince);
15565                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15566                } else {
15567                    app.lastWakeTime = wtime;
15568                    app.lastCpuTime = app.curCpuTime;
15569                }
15570            }
15571        }
15572    }
15573
15574    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15575            ProcessRecord TOP_APP, boolean doingAll, long now) {
15576        boolean success = true;
15577
15578        if (app.curRawAdj != app.setRawAdj) {
15579            if (wasKeeping && !app.keeping) {
15580                // This app is no longer something we want to keep.  Note
15581                // its current wake lock time to later know to kill it if
15582                // it is not behaving well.
15583                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15584                synchronized (stats) {
15585                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15586                            app.pid, SystemClock.elapsedRealtime());
15587                }
15588                app.lastCpuTime = app.curCpuTime;
15589            }
15590
15591            app.setRawAdj = app.curRawAdj;
15592        }
15593
15594        int changes = 0;
15595
15596        if (app.curAdj != app.setAdj) {
15597            ProcessList.setOomAdj(app.pid, app.curAdj);
15598            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15599                TAG, "Set " + app.pid + " " + app.processName +
15600                " adj " + app.curAdj + ": " + app.adjType);
15601            app.setAdj = app.curAdj;
15602        }
15603
15604        if (app.setSchedGroup != app.curSchedGroup) {
15605            app.setSchedGroup = app.curSchedGroup;
15606            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15607                    "Setting process group of " + app.processName
15608                    + " to " + app.curSchedGroup);
15609            if (app.waitingToKill != null &&
15610                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15611                killUnneededProcessLocked(app, app.waitingToKill);
15612                success = false;
15613            } else {
15614                if (true) {
15615                    long oldId = Binder.clearCallingIdentity();
15616                    try {
15617                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15618                    } catch (Exception e) {
15619                        Slog.w(TAG, "Failed setting process group of " + app.pid
15620                                + " to " + app.curSchedGroup);
15621                        e.printStackTrace();
15622                    } finally {
15623                        Binder.restoreCallingIdentity(oldId);
15624                    }
15625                } else {
15626                    if (app.thread != null) {
15627                        try {
15628                            app.thread.setSchedulingGroup(app.curSchedGroup);
15629                        } catch (RemoteException e) {
15630                        }
15631                    }
15632                }
15633                Process.setSwappiness(app.pid,
15634                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15635            }
15636        }
15637        if (app.repForegroundActivities != app.foregroundActivities) {
15638            app.repForegroundActivities = app.foregroundActivities;
15639            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15640        }
15641        if (app.repProcState != app.curProcState) {
15642            app.repProcState = app.curProcState;
15643            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15644            if (app.thread != null) {
15645                try {
15646                    if (false) {
15647                        //RuntimeException h = new RuntimeException("here");
15648                        Slog.i(TAG, "Sending new process state " + app.repProcState
15649                                + " to " + app /*, h*/);
15650                    }
15651                    app.thread.setProcessState(app.repProcState);
15652                } catch (RemoteException e) {
15653                }
15654            }
15655        }
15656        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15657                app.setProcState)) {
15658            app.lastStateTime = now;
15659            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15660                    isSleeping(), now);
15661            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15662                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15663                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15664                    + (app.nextPssTime-now) + ": " + app);
15665        } else {
15666            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15667                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15668                requestPssLocked(app, app.setProcState);
15669                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15670                        isSleeping(), now);
15671            } else if (false && DEBUG_PSS) {
15672                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15673            }
15674        }
15675        if (app.setProcState != app.curProcState) {
15676            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15677                    "Proc state change of " + app.processName
15678                    + " to " + app.curProcState);
15679            app.setProcState = app.curProcState;
15680            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15681                app.notCachedSinceIdle = false;
15682            }
15683            if (!doingAll) {
15684                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15685            } else {
15686                app.procStateChanged = true;
15687            }
15688        }
15689
15690        if (changes != 0) {
15691            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15692            int i = mPendingProcessChanges.size()-1;
15693            ProcessChangeItem item = null;
15694            while (i >= 0) {
15695                item = mPendingProcessChanges.get(i);
15696                if (item.pid == app.pid) {
15697                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15698                    break;
15699                }
15700                i--;
15701            }
15702            if (i < 0) {
15703                // No existing item in pending changes; need a new one.
15704                final int NA = mAvailProcessChanges.size();
15705                if (NA > 0) {
15706                    item = mAvailProcessChanges.remove(NA-1);
15707                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15708                } else {
15709                    item = new ProcessChangeItem();
15710                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15711                }
15712                item.changes = 0;
15713                item.pid = app.pid;
15714                item.uid = app.info.uid;
15715                if (mPendingProcessChanges.size() == 0) {
15716                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15717                            "*** Enqueueing dispatch processes changed!");
15718                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15719                }
15720                mPendingProcessChanges.add(item);
15721            }
15722            item.changes |= changes;
15723            item.processState = app.repProcState;
15724            item.foregroundActivities = app.repForegroundActivities;
15725            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15726                    + Integer.toHexString(System.identityHashCode(item))
15727                    + " " + app.toShortString() + ": changes=" + item.changes
15728                    + " procState=" + item.processState
15729                    + " foreground=" + item.foregroundActivities
15730                    + " type=" + app.adjType + " source=" + app.adjSource
15731                    + " target=" + app.adjTarget);
15732        }
15733
15734        return success;
15735    }
15736
15737    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15738        if (proc.thread != null && proc.baseProcessTracker != null) {
15739            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15740        }
15741    }
15742
15743    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15744            ProcessRecord TOP_APP, boolean doingAll, long now) {
15745        if (app.thread == null) {
15746            return false;
15747        }
15748
15749        final boolean wasKeeping = app.keeping;
15750
15751        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15752
15753        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15754    }
15755
15756    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15757            boolean oomAdj) {
15758        if (isForeground != proc.foregroundServices) {
15759            proc.foregroundServices = isForeground;
15760            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15761                    proc.info.uid);
15762            if (isForeground) {
15763                if (curProcs == null) {
15764                    curProcs = new ArrayList<ProcessRecord>();
15765                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15766                }
15767                if (!curProcs.contains(proc)) {
15768                    curProcs.add(proc);
15769                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15770                            proc.info.packageName, proc.info.uid);
15771                }
15772            } else {
15773                if (curProcs != null) {
15774                    if (curProcs.remove(proc)) {
15775                        mBatteryStatsService.noteEvent(
15776                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15777                                proc.info.packageName, proc.info.uid);
15778                        if (curProcs.size() <= 0) {
15779                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15780                        }
15781                    }
15782                }
15783            }
15784            if (oomAdj) {
15785                updateOomAdjLocked();
15786            }
15787        }
15788    }
15789
15790    private final ActivityRecord resumedAppLocked() {
15791        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15792        String pkg;
15793        int uid;
15794        if (act != null && !act.sleeping) {
15795            pkg = act.packageName;
15796            uid = act.info.applicationInfo.uid;
15797        } else {
15798            pkg = null;
15799            uid = -1;
15800        }
15801        // Has the UID or resumed package name changed?
15802        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15803                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15804            if (mCurResumedPackage != null) {
15805                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15806                        mCurResumedPackage, mCurResumedUid);
15807            }
15808            mCurResumedPackage = pkg;
15809            mCurResumedUid = uid;
15810            if (mCurResumedPackage != null) {
15811                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15812                        mCurResumedPackage, mCurResumedUid);
15813            }
15814        }
15815        return act;
15816    }
15817
15818    final boolean updateOomAdjLocked(ProcessRecord app) {
15819        final ActivityRecord TOP_ACT = resumedAppLocked();
15820        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15821        final boolean wasCached = app.cached;
15822
15823        mAdjSeq++;
15824
15825        // This is the desired cached adjusment we want to tell it to use.
15826        // If our app is currently cached, we know it, and that is it.  Otherwise,
15827        // we don't know it yet, and it needs to now be cached we will then
15828        // need to do a complete oom adj.
15829        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15830                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15831        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15832                SystemClock.uptimeMillis());
15833        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15834            // Changed to/from cached state, so apps after it in the LRU
15835            // list may also be changed.
15836            updateOomAdjLocked();
15837        }
15838        return success;
15839    }
15840
15841    final void updateOomAdjLocked() {
15842        final ActivityRecord TOP_ACT = resumedAppLocked();
15843        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15844        final long now = SystemClock.uptimeMillis();
15845        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15846        final int N = mLruProcesses.size();
15847
15848        if (false) {
15849            RuntimeException e = new RuntimeException();
15850            e.fillInStackTrace();
15851            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15852        }
15853
15854        mAdjSeq++;
15855        mNewNumServiceProcs = 0;
15856        mNewNumAServiceProcs = 0;
15857
15858        final int emptyProcessLimit;
15859        final int cachedProcessLimit;
15860        if (mProcessLimit <= 0) {
15861            emptyProcessLimit = cachedProcessLimit = 0;
15862        } else if (mProcessLimit == 1) {
15863            emptyProcessLimit = 1;
15864            cachedProcessLimit = 0;
15865        } else {
15866            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15867            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15868        }
15869
15870        // Let's determine how many processes we have running vs.
15871        // how many slots we have for background processes; we may want
15872        // to put multiple processes in a slot of there are enough of
15873        // them.
15874        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15875                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15876        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15877        if (numEmptyProcs > cachedProcessLimit) {
15878            // If there are more empty processes than our limit on cached
15879            // processes, then use the cached process limit for the factor.
15880            // This ensures that the really old empty processes get pushed
15881            // down to the bottom, so if we are running low on memory we will
15882            // have a better chance at keeping around more cached processes
15883            // instead of a gazillion empty processes.
15884            numEmptyProcs = cachedProcessLimit;
15885        }
15886        int emptyFactor = numEmptyProcs/numSlots;
15887        if (emptyFactor < 1) emptyFactor = 1;
15888        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15889        if (cachedFactor < 1) cachedFactor = 1;
15890        int stepCached = 0;
15891        int stepEmpty = 0;
15892        int numCached = 0;
15893        int numEmpty = 0;
15894        int numTrimming = 0;
15895
15896        mNumNonCachedProcs = 0;
15897        mNumCachedHiddenProcs = 0;
15898
15899        // First update the OOM adjustment for each of the
15900        // application processes based on their current state.
15901        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15902        int nextCachedAdj = curCachedAdj+1;
15903        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15904        int nextEmptyAdj = curEmptyAdj+2;
15905        for (int i=N-1; i>=0; i--) {
15906            ProcessRecord app = mLruProcesses.get(i);
15907            if (!app.killedByAm && app.thread != null) {
15908                app.procStateChanged = false;
15909                final boolean wasKeeping = app.keeping;
15910                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15911
15912                // If we haven't yet assigned the final cached adj
15913                // to the process, do that now.
15914                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15915                    switch (app.curProcState) {
15916                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15917                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15918                            // This process is a cached process holding activities...
15919                            // assign it the next cached value for that type, and then
15920                            // step that cached level.
15921                            app.curRawAdj = curCachedAdj;
15922                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15923                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15924                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15925                                    + ")");
15926                            if (curCachedAdj != nextCachedAdj) {
15927                                stepCached++;
15928                                if (stepCached >= cachedFactor) {
15929                                    stepCached = 0;
15930                                    curCachedAdj = nextCachedAdj;
15931                                    nextCachedAdj += 2;
15932                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15933                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15934                                    }
15935                                }
15936                            }
15937                            break;
15938                        default:
15939                            // For everything else, assign next empty cached process
15940                            // level and bump that up.  Note that this means that
15941                            // long-running services that have dropped down to the
15942                            // cached level will be treated as empty (since their process
15943                            // state is still as a service), which is what we want.
15944                            app.curRawAdj = curEmptyAdj;
15945                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15946                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15947                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15948                                    + ")");
15949                            if (curEmptyAdj != nextEmptyAdj) {
15950                                stepEmpty++;
15951                                if (stepEmpty >= emptyFactor) {
15952                                    stepEmpty = 0;
15953                                    curEmptyAdj = nextEmptyAdj;
15954                                    nextEmptyAdj += 2;
15955                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15956                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15957                                    }
15958                                }
15959                            }
15960                            break;
15961                    }
15962                }
15963
15964                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15965
15966                // Count the number of process types.
15967                switch (app.curProcState) {
15968                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15969                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15970                        mNumCachedHiddenProcs++;
15971                        numCached++;
15972                        if (numCached > cachedProcessLimit) {
15973                            killUnneededProcessLocked(app, "cached #" + numCached);
15974                        }
15975                        break;
15976                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15977                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15978                                && app.lastActivityTime < oldTime) {
15979                            killUnneededProcessLocked(app, "empty for "
15980                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15981                                    / 1000) + "s");
15982                        } else {
15983                            numEmpty++;
15984                            if (numEmpty > emptyProcessLimit) {
15985                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15986                            }
15987                        }
15988                        break;
15989                    default:
15990                        mNumNonCachedProcs++;
15991                        break;
15992                }
15993
15994                if (app.isolated && app.services.size() <= 0) {
15995                    // If this is an isolated process, and there are no
15996                    // services running in it, then the process is no longer
15997                    // needed.  We agressively kill these because we can by
15998                    // definition not re-use the same process again, and it is
15999                    // good to avoid having whatever code was running in them
16000                    // left sitting around after no longer needed.
16001                    killUnneededProcessLocked(app, "isolated not needed");
16002                }
16003
16004                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16005                        && !app.killedByAm) {
16006                    numTrimming++;
16007                }
16008            }
16009        }
16010
16011        mNumServiceProcs = mNewNumServiceProcs;
16012
16013        // Now determine the memory trimming level of background processes.
16014        // Unfortunately we need to start at the back of the list to do this
16015        // properly.  We only do this if the number of background apps we
16016        // are managing to keep around is less than half the maximum we desire;
16017        // if we are keeping a good number around, we'll let them use whatever
16018        // memory they want.
16019        final int numCachedAndEmpty = numCached + numEmpty;
16020        int memFactor;
16021        if (numCached <= ProcessList.TRIM_CACHED_APPS
16022                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16023            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16024                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16025            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16026                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16027            } else {
16028                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16029            }
16030        } else {
16031            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16032        }
16033        // We always allow the memory level to go up (better).  We only allow it to go
16034        // down if we are in a state where that is allowed, *and* the total number of processes
16035        // has gone down since last time.
16036        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16037                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16038                + " last=" + mLastNumProcesses);
16039        if (memFactor > mLastMemoryLevel) {
16040            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16041                memFactor = mLastMemoryLevel;
16042                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16043            }
16044        }
16045        mLastMemoryLevel = memFactor;
16046        mLastNumProcesses = mLruProcesses.size();
16047        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16048        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16049        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16050            if (mLowRamStartTime == 0) {
16051                mLowRamStartTime = now;
16052            }
16053            int step = 0;
16054            int fgTrimLevel;
16055            switch (memFactor) {
16056                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16057                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16058                    break;
16059                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16060                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16061                    break;
16062                default:
16063                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16064                    break;
16065            }
16066            int factor = numTrimming/3;
16067            int minFactor = 2;
16068            if (mHomeProcess != null) minFactor++;
16069            if (mPreviousProcess != null) minFactor++;
16070            if (factor < minFactor) factor = minFactor;
16071            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16072            for (int i=N-1; i>=0; i--) {
16073                ProcessRecord app = mLruProcesses.get(i);
16074                if (allChanged || app.procStateChanged) {
16075                    setProcessTrackerState(app, trackerMemFactor, now);
16076                    app.procStateChanged = false;
16077                }
16078                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16079                        && !app.killedByAm) {
16080                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16081                        try {
16082                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16083                                    "Trimming memory of " + app.processName
16084                                    + " to " + curLevel);
16085                            app.thread.scheduleTrimMemory(curLevel);
16086                        } catch (RemoteException e) {
16087                        }
16088                        if (false) {
16089                            // For now we won't do this; our memory trimming seems
16090                            // to be good enough at this point that destroying
16091                            // activities causes more harm than good.
16092                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16093                                    && app != mHomeProcess && app != mPreviousProcess) {
16094                                // Need to do this on its own message because the stack may not
16095                                // be in a consistent state at this point.
16096                                // For these apps we will also finish their activities
16097                                // to help them free memory.
16098                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16099                            }
16100                        }
16101                    }
16102                    app.trimMemoryLevel = curLevel;
16103                    step++;
16104                    if (step >= factor) {
16105                        step = 0;
16106                        switch (curLevel) {
16107                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16108                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16109                                break;
16110                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16111                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16112                                break;
16113                        }
16114                    }
16115                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16116                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16117                            && app.thread != null) {
16118                        try {
16119                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16120                                    "Trimming memory of heavy-weight " + app.processName
16121                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16122                            app.thread.scheduleTrimMemory(
16123                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16124                        } catch (RemoteException e) {
16125                        }
16126                    }
16127                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16128                } else {
16129                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16130                            || app.systemNoUi) && app.pendingUiClean) {
16131                        // If this application is now in the background and it
16132                        // had done UI, then give it the special trim level to
16133                        // have it free UI resources.
16134                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16135                        if (app.trimMemoryLevel < level && app.thread != null) {
16136                            try {
16137                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16138                                        "Trimming memory of bg-ui " + app.processName
16139                                        + " to " + level);
16140                                app.thread.scheduleTrimMemory(level);
16141                            } catch (RemoteException e) {
16142                            }
16143                        }
16144                        app.pendingUiClean = false;
16145                    }
16146                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16147                        try {
16148                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16149                                    "Trimming memory of fg " + app.processName
16150                                    + " to " + fgTrimLevel);
16151                            app.thread.scheduleTrimMemory(fgTrimLevel);
16152                        } catch (RemoteException e) {
16153                        }
16154                    }
16155                    app.trimMemoryLevel = fgTrimLevel;
16156                }
16157            }
16158        } else {
16159            if (mLowRamStartTime != 0) {
16160                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16161                mLowRamStartTime = 0;
16162            }
16163            for (int i=N-1; i>=0; i--) {
16164                ProcessRecord app = mLruProcesses.get(i);
16165                if (allChanged || app.procStateChanged) {
16166                    setProcessTrackerState(app, trackerMemFactor, now);
16167                    app.procStateChanged = false;
16168                }
16169                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16170                        || app.systemNoUi) && app.pendingUiClean) {
16171                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16172                            && app.thread != null) {
16173                        try {
16174                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16175                                    "Trimming memory of ui hidden " + app.processName
16176                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16177                            app.thread.scheduleTrimMemory(
16178                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16179                        } catch (RemoteException e) {
16180                        }
16181                    }
16182                    app.pendingUiClean = false;
16183                }
16184                app.trimMemoryLevel = 0;
16185            }
16186        }
16187
16188        if (mAlwaysFinishActivities) {
16189            // Need to do this on its own message because the stack may not
16190            // be in a consistent state at this point.
16191            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16192        }
16193
16194        if (allChanged) {
16195            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16196        }
16197
16198        if (mProcessStats.shouldWriteNowLocked(now)) {
16199            mHandler.post(new Runnable() {
16200                @Override public void run() {
16201                    synchronized (ActivityManagerService.this) {
16202                        mProcessStats.writeStateAsyncLocked();
16203                    }
16204                }
16205            });
16206        }
16207
16208        if (DEBUG_OOM_ADJ) {
16209            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16210        }
16211    }
16212
16213    final void trimApplications() {
16214        synchronized (this) {
16215            int i;
16216
16217            // First remove any unused application processes whose package
16218            // has been removed.
16219            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16220                final ProcessRecord app = mRemovedProcesses.get(i);
16221                if (app.activities.size() == 0
16222                        && app.curReceiver == null && app.services.size() == 0) {
16223                    Slog.i(
16224                        TAG, "Exiting empty application process "
16225                        + app.processName + " ("
16226                        + (app.thread != null ? app.thread.asBinder() : null)
16227                        + ")\n");
16228                    if (app.pid > 0 && app.pid != MY_PID) {
16229                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16230                                app.processName, app.setAdj, "empty");
16231                        app.killedByAm = true;
16232                        Process.killProcessQuiet(app.pid);
16233                    } else {
16234                        try {
16235                            app.thread.scheduleExit();
16236                        } catch (Exception e) {
16237                            // Ignore exceptions.
16238                        }
16239                    }
16240                    cleanUpApplicationRecordLocked(app, false, true, -1);
16241                    mRemovedProcesses.remove(i);
16242
16243                    if (app.persistent) {
16244                        if (app.persistent) {
16245                            addAppLocked(app.info, false);
16246                        }
16247                    }
16248                }
16249            }
16250
16251            // Now update the oom adj for all processes.
16252            updateOomAdjLocked();
16253        }
16254    }
16255
16256    /** This method sends the specified signal to each of the persistent apps */
16257    public void signalPersistentProcesses(int sig) throws RemoteException {
16258        if (sig != Process.SIGNAL_USR1) {
16259            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16260        }
16261
16262        synchronized (this) {
16263            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16264                    != PackageManager.PERMISSION_GRANTED) {
16265                throw new SecurityException("Requires permission "
16266                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16267            }
16268
16269            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16270                ProcessRecord r = mLruProcesses.get(i);
16271                if (r.thread != null && r.persistent) {
16272                    Process.sendSignal(r.pid, sig);
16273                }
16274            }
16275        }
16276    }
16277
16278    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16279        if (proc == null || proc == mProfileProc) {
16280            proc = mProfileProc;
16281            path = mProfileFile;
16282            profileType = mProfileType;
16283            clearProfilerLocked();
16284        }
16285        if (proc == null) {
16286            return;
16287        }
16288        try {
16289            proc.thread.profilerControl(false, path, null, profileType);
16290        } catch (RemoteException e) {
16291            throw new IllegalStateException("Process disappeared");
16292        }
16293    }
16294
16295    private void clearProfilerLocked() {
16296        if (mProfileFd != null) {
16297            try {
16298                mProfileFd.close();
16299            } catch (IOException e) {
16300            }
16301        }
16302        mProfileApp = null;
16303        mProfileProc = null;
16304        mProfileFile = null;
16305        mProfileType = 0;
16306        mAutoStopProfiler = false;
16307    }
16308
16309    public boolean profileControl(String process, int userId, boolean start,
16310            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16311
16312        try {
16313            synchronized (this) {
16314                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16315                // its own permission.
16316                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16317                        != PackageManager.PERMISSION_GRANTED) {
16318                    throw new SecurityException("Requires permission "
16319                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16320                }
16321
16322                if (start && fd == null) {
16323                    throw new IllegalArgumentException("null fd");
16324                }
16325
16326                ProcessRecord proc = null;
16327                if (process != null) {
16328                    proc = findProcessLocked(process, userId, "profileControl");
16329                }
16330
16331                if (start && (proc == null || proc.thread == null)) {
16332                    throw new IllegalArgumentException("Unknown process: " + process);
16333                }
16334
16335                if (start) {
16336                    stopProfilerLocked(null, null, 0);
16337                    setProfileApp(proc.info, proc.processName, path, fd, false);
16338                    mProfileProc = proc;
16339                    mProfileType = profileType;
16340                    try {
16341                        fd = fd.dup();
16342                    } catch (IOException e) {
16343                        fd = null;
16344                    }
16345                    proc.thread.profilerControl(start, path, fd, profileType);
16346                    fd = null;
16347                    mProfileFd = null;
16348                } else {
16349                    stopProfilerLocked(proc, path, profileType);
16350                    if (fd != null) {
16351                        try {
16352                            fd.close();
16353                        } catch (IOException e) {
16354                        }
16355                    }
16356                }
16357
16358                return true;
16359            }
16360        } catch (RemoteException e) {
16361            throw new IllegalStateException("Process disappeared");
16362        } finally {
16363            if (fd != null) {
16364                try {
16365                    fd.close();
16366                } catch (IOException e) {
16367                }
16368            }
16369        }
16370    }
16371
16372    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16374                userId, true, true, callName, null);
16375        ProcessRecord proc = null;
16376        try {
16377            int pid = Integer.parseInt(process);
16378            synchronized (mPidsSelfLocked) {
16379                proc = mPidsSelfLocked.get(pid);
16380            }
16381        } catch (NumberFormatException e) {
16382        }
16383
16384        if (proc == null) {
16385            ArrayMap<String, SparseArray<ProcessRecord>> all
16386                    = mProcessNames.getMap();
16387            SparseArray<ProcessRecord> procs = all.get(process);
16388            if (procs != null && procs.size() > 0) {
16389                proc = procs.valueAt(0);
16390                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16391                    for (int i=1; i<procs.size(); i++) {
16392                        ProcessRecord thisProc = procs.valueAt(i);
16393                        if (thisProc.userId == userId) {
16394                            proc = thisProc;
16395                            break;
16396                        }
16397                    }
16398                }
16399            }
16400        }
16401
16402        return proc;
16403    }
16404
16405    public boolean dumpHeap(String process, int userId, boolean managed,
16406            String path, ParcelFileDescriptor fd) throws RemoteException {
16407
16408        try {
16409            synchronized (this) {
16410                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16411                // its own permission (same as profileControl).
16412                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16413                        != PackageManager.PERMISSION_GRANTED) {
16414                    throw new SecurityException("Requires permission "
16415                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16416                }
16417
16418                if (fd == null) {
16419                    throw new IllegalArgumentException("null fd");
16420                }
16421
16422                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16423                if (proc == null || proc.thread == null) {
16424                    throw new IllegalArgumentException("Unknown process: " + process);
16425                }
16426
16427                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16428                if (!isDebuggable) {
16429                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16430                        throw new SecurityException("Process not debuggable: " + proc);
16431                    }
16432                }
16433
16434                proc.thread.dumpHeap(managed, path, fd);
16435                fd = null;
16436                return true;
16437            }
16438        } catch (RemoteException e) {
16439            throw new IllegalStateException("Process disappeared");
16440        } finally {
16441            if (fd != null) {
16442                try {
16443                    fd.close();
16444                } catch (IOException e) {
16445                }
16446            }
16447        }
16448    }
16449
16450    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16451    public void monitor() {
16452        synchronized (this) { }
16453    }
16454
16455    void onCoreSettingsChange(Bundle settings) {
16456        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16457            ProcessRecord processRecord = mLruProcesses.get(i);
16458            try {
16459                if (processRecord.thread != null) {
16460                    processRecord.thread.setCoreSettings(settings);
16461                }
16462            } catch (RemoteException re) {
16463                /* ignore */
16464            }
16465        }
16466    }
16467
16468    // Multi-user methods
16469
16470    /**
16471     * Start user, if its not already running, but don't bring it to foreground.
16472     */
16473    @Override
16474    public boolean startUserInBackground(final int userId) {
16475        return startUser(userId, /* foreground */ false);
16476    }
16477
16478    /**
16479     * Refreshes the list of users related to the current user when either a
16480     * user switch happens or when a new related user is started in the
16481     * background.
16482     */
16483    private void updateCurrentProfileIdsLocked() {
16484        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16485                mCurrentUserId, false /* enabledOnly */);
16486        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16487        for (int i = 0; i < currentProfileIds.length; i++) {
16488            currentProfileIds[i] = profiles.get(i).id;
16489        }
16490        mCurrentProfileIds = currentProfileIds;
16491    }
16492
16493    private Set getProfileIdsLocked(int userId) {
16494        Set userIds = new HashSet<Integer>();
16495        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16496                userId, false /* enabledOnly */);
16497        for (UserInfo user : profiles) {
16498            userIds.add(Integer.valueOf(user.id));
16499        }
16500        return userIds;
16501    }
16502
16503    @Override
16504    public boolean switchUser(final int userId) {
16505        return startUser(userId, /* foregound */ true);
16506    }
16507
16508    private boolean startUser(final int userId, boolean foreground) {
16509        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16510                != PackageManager.PERMISSION_GRANTED) {
16511            String msg = "Permission Denial: switchUser() from pid="
16512                    + Binder.getCallingPid()
16513                    + ", uid=" + Binder.getCallingUid()
16514                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16515            Slog.w(TAG, msg);
16516            throw new SecurityException(msg);
16517        }
16518
16519        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16520
16521        final long ident = Binder.clearCallingIdentity();
16522        try {
16523            synchronized (this) {
16524                final int oldUserId = mCurrentUserId;
16525                if (oldUserId == userId) {
16526                    return true;
16527                }
16528
16529                mStackSupervisor.setLockTaskModeLocked(null);
16530
16531                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16532                if (userInfo == null) {
16533                    Slog.w(TAG, "No user info for user #" + userId);
16534                    return false;
16535                }
16536
16537                if (foreground) {
16538                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16539                            R.anim.screen_user_enter);
16540                }
16541
16542                boolean needStart = false;
16543
16544                // If the user we are switching to is not currently started, then
16545                // we need to start it now.
16546                if (mStartedUsers.get(userId) == null) {
16547                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16548                    updateStartedUserArrayLocked();
16549                    needStart = true;
16550                }
16551
16552                final Integer userIdInt = Integer.valueOf(userId);
16553                mUserLru.remove(userIdInt);
16554                mUserLru.add(userIdInt);
16555
16556                if (foreground) {
16557                    mCurrentUserId = userId;
16558                    updateCurrentProfileIdsLocked();
16559                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16560                    // Once the internal notion of the active user has switched, we lock the device
16561                    // with the option to show the user switcher on the keyguard.
16562                    mWindowManager.lockNow(null);
16563                } else {
16564                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16565                    updateCurrentProfileIdsLocked();
16566                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16567                    mUserLru.remove(currentUserIdInt);
16568                    mUserLru.add(currentUserIdInt);
16569                }
16570
16571                final UserStartedState uss = mStartedUsers.get(userId);
16572
16573                // Make sure user is in the started state.  If it is currently
16574                // stopping, we need to knock that off.
16575                if (uss.mState == UserStartedState.STATE_STOPPING) {
16576                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16577                    // so we can just fairly silently bring the user back from
16578                    // the almost-dead.
16579                    uss.mState = UserStartedState.STATE_RUNNING;
16580                    updateStartedUserArrayLocked();
16581                    needStart = true;
16582                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16583                    // This means ACTION_SHUTDOWN has been sent, so we will
16584                    // need to treat this as a new boot of the user.
16585                    uss.mState = UserStartedState.STATE_BOOTING;
16586                    updateStartedUserArrayLocked();
16587                    needStart = true;
16588                }
16589
16590                if (uss.mState == UserStartedState.STATE_BOOTING) {
16591                    // Booting up a new user, need to tell system services about it.
16592                    // Note that this is on the same handler as scheduling of broadcasts,
16593                    // which is important because it needs to go first.
16594                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16595                }
16596
16597                if (foreground) {
16598                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16599                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16600                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16601                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16602                            oldUserId, userId, uss));
16603                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16604                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16605                }
16606
16607                if (needStart) {
16608                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16609                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16610                            | Intent.FLAG_RECEIVER_FOREGROUND);
16611                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16612                    broadcastIntentLocked(null, null, intent,
16613                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16614                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16615                }
16616
16617                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16618                    if (userId != UserHandle.USER_OWNER) {
16619                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16620                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16621                        broadcastIntentLocked(null, null, intent, null,
16622                                new IIntentReceiver.Stub() {
16623                                    public void performReceive(Intent intent, int resultCode,
16624                                            String data, Bundle extras, boolean ordered,
16625                                            boolean sticky, int sendingUser) {
16626                                        userInitialized(uss, userId);
16627                                    }
16628                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16629                                true, false, MY_PID, Process.SYSTEM_UID,
16630                                userId);
16631                        uss.initializing = true;
16632                    } else {
16633                        getUserManagerLocked().makeInitialized(userInfo.id);
16634                    }
16635                }
16636
16637                if (foreground) {
16638                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16639                    if (homeInFront) {
16640                        startHomeActivityLocked(userId);
16641                    } else {
16642                        mStackSupervisor.resumeTopActivitiesLocked();
16643                    }
16644                    EventLogTags.writeAmSwitchUser(userId);
16645                    getUserManagerLocked().userForeground(userId);
16646                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16647                } else {
16648                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16649                }
16650
16651                if (needStart) {
16652                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16653                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16654                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16655                    broadcastIntentLocked(null, null, intent,
16656                            null, new IIntentReceiver.Stub() {
16657                                @Override
16658                                public void performReceive(Intent intent, int resultCode, String data,
16659                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16660                                        throws RemoteException {
16661                                }
16662                            }, 0, null, null,
16663                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16664                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16665                }
16666            }
16667        } finally {
16668            Binder.restoreCallingIdentity(ident);
16669        }
16670
16671        return true;
16672    }
16673
16674    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16675        long ident = Binder.clearCallingIdentity();
16676        try {
16677            Intent intent;
16678            if (oldUserId >= 0) {
16679                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16680                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16681                        | Intent.FLAG_RECEIVER_FOREGROUND);
16682                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16683                broadcastIntentLocked(null, null, intent,
16684                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16685                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16686            }
16687            if (newUserId >= 0) {
16688                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16689                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16690                        | Intent.FLAG_RECEIVER_FOREGROUND);
16691                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16692                broadcastIntentLocked(null, null, intent,
16693                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16694                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16695                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16696                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16697                        | Intent.FLAG_RECEIVER_FOREGROUND);
16698                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16699                broadcastIntentLocked(null, null, intent,
16700                        null, null, 0, null, null,
16701                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16702                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16703            }
16704        } finally {
16705            Binder.restoreCallingIdentity(ident);
16706        }
16707    }
16708
16709    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16710            final int newUserId) {
16711        final int N = mUserSwitchObservers.beginBroadcast();
16712        if (N > 0) {
16713            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16714                int mCount = 0;
16715                @Override
16716                public void sendResult(Bundle data) throws RemoteException {
16717                    synchronized (ActivityManagerService.this) {
16718                        if (mCurUserSwitchCallback == this) {
16719                            mCount++;
16720                            if (mCount == N) {
16721                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16722                            }
16723                        }
16724                    }
16725                }
16726            };
16727            synchronized (this) {
16728                uss.switching = true;
16729                mCurUserSwitchCallback = callback;
16730            }
16731            for (int i=0; i<N; i++) {
16732                try {
16733                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16734                            newUserId, callback);
16735                } catch (RemoteException e) {
16736                }
16737            }
16738        } else {
16739            synchronized (this) {
16740                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16741            }
16742        }
16743        mUserSwitchObservers.finishBroadcast();
16744    }
16745
16746    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16747        synchronized (this) {
16748            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16749            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16750        }
16751    }
16752
16753    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16754        mCurUserSwitchCallback = null;
16755        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16756        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16757                oldUserId, newUserId, uss));
16758    }
16759
16760    void userInitialized(UserStartedState uss, int newUserId) {
16761        completeSwitchAndInitalize(uss, newUserId, true, false);
16762    }
16763
16764    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16765        completeSwitchAndInitalize(uss, newUserId, false, true);
16766    }
16767
16768    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16769            boolean clearInitializing, boolean clearSwitching) {
16770        boolean unfrozen = false;
16771        synchronized (this) {
16772            if (clearInitializing) {
16773                uss.initializing = false;
16774                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16775            }
16776            if (clearSwitching) {
16777                uss.switching = false;
16778            }
16779            if (!uss.switching && !uss.initializing) {
16780                mWindowManager.stopFreezingScreen();
16781                unfrozen = true;
16782            }
16783        }
16784        if (unfrozen) {
16785            final int N = mUserSwitchObservers.beginBroadcast();
16786            for (int i=0; i<N; i++) {
16787                try {
16788                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16789                } catch (RemoteException e) {
16790                }
16791            }
16792            mUserSwitchObservers.finishBroadcast();
16793        }
16794    }
16795
16796    void scheduleStartProfilesLocked() {
16797        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16798            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16799                    DateUtils.SECOND_IN_MILLIS);
16800        }
16801    }
16802
16803    void startProfilesLocked() {
16804        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16805        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16806                mCurrentUserId, false /* enabledOnly */);
16807        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16808        for (UserInfo user : profiles) {
16809            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16810                    && user.id != mCurrentUserId) {
16811                toStart.add(user);
16812            }
16813        }
16814        final int n = toStart.size();
16815        int i = 0;
16816        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16817            startUserInBackground(toStart.get(i).id);
16818        }
16819        if (i < n) {
16820            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16821        }
16822    }
16823
16824    void finishUserBoot(UserStartedState uss) {
16825        synchronized (this) {
16826            if (uss.mState == UserStartedState.STATE_BOOTING
16827                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16828                uss.mState = UserStartedState.STATE_RUNNING;
16829                final int userId = uss.mHandle.getIdentifier();
16830                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16831                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16832                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16833                broadcastIntentLocked(null, null, intent,
16834                        null, null, 0, null, null,
16835                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16836                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16837            }
16838        }
16839    }
16840
16841    void finishUserSwitch(UserStartedState uss) {
16842        synchronized (this) {
16843            finishUserBoot(uss);
16844
16845            startProfilesLocked();
16846
16847            int num = mUserLru.size();
16848            int i = 0;
16849            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16850                Integer oldUserId = mUserLru.get(i);
16851                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16852                if (oldUss == null) {
16853                    // Shouldn't happen, but be sane if it does.
16854                    mUserLru.remove(i);
16855                    num--;
16856                    continue;
16857                }
16858                if (oldUss.mState == UserStartedState.STATE_STOPPING
16859                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16860                    // This user is already stopping, doesn't count.
16861                    num--;
16862                    i++;
16863                    continue;
16864                }
16865                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16866                    // Owner and current can't be stopped, but count as running.
16867                    i++;
16868                    continue;
16869                }
16870                // This is a user to be stopped.
16871                stopUserLocked(oldUserId, null);
16872                num--;
16873                i++;
16874            }
16875        }
16876    }
16877
16878    @Override
16879    public int stopUser(final int userId, final IStopUserCallback callback) {
16880        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16881                != PackageManager.PERMISSION_GRANTED) {
16882            String msg = "Permission Denial: switchUser() from pid="
16883                    + Binder.getCallingPid()
16884                    + ", uid=" + Binder.getCallingUid()
16885                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16886            Slog.w(TAG, msg);
16887            throw new SecurityException(msg);
16888        }
16889        if (userId <= 0) {
16890            throw new IllegalArgumentException("Can't stop primary user " + userId);
16891        }
16892        synchronized (this) {
16893            return stopUserLocked(userId, callback);
16894        }
16895    }
16896
16897    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16898        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16899        if (mCurrentUserId == userId) {
16900            return ActivityManager.USER_OP_IS_CURRENT;
16901        }
16902
16903        final UserStartedState uss = mStartedUsers.get(userId);
16904        if (uss == null) {
16905            // User is not started, nothing to do...  but we do need to
16906            // callback if requested.
16907            if (callback != null) {
16908                mHandler.post(new Runnable() {
16909                    @Override
16910                    public void run() {
16911                        try {
16912                            callback.userStopped(userId);
16913                        } catch (RemoteException e) {
16914                        }
16915                    }
16916                });
16917            }
16918            return ActivityManager.USER_OP_SUCCESS;
16919        }
16920
16921        if (callback != null) {
16922            uss.mStopCallbacks.add(callback);
16923        }
16924
16925        if (uss.mState != UserStartedState.STATE_STOPPING
16926                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16927            uss.mState = UserStartedState.STATE_STOPPING;
16928            updateStartedUserArrayLocked();
16929
16930            long ident = Binder.clearCallingIdentity();
16931            try {
16932                // We are going to broadcast ACTION_USER_STOPPING and then
16933                // once that is done send a final ACTION_SHUTDOWN and then
16934                // stop the user.
16935                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16936                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16937                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16938                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16939                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16940                // This is the result receiver for the final shutdown broadcast.
16941                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16942                    @Override
16943                    public void performReceive(Intent intent, int resultCode, String data,
16944                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16945                        finishUserStop(uss);
16946                    }
16947                };
16948                // This is the result receiver for the initial stopping broadcast.
16949                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16950                    @Override
16951                    public void performReceive(Intent intent, int resultCode, String data,
16952                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16953                        // On to the next.
16954                        synchronized (ActivityManagerService.this) {
16955                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16956                                // Whoops, we are being started back up.  Abort, abort!
16957                                return;
16958                            }
16959                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16960                        }
16961                        mSystemServiceManager.stopUser(userId);
16962                        broadcastIntentLocked(null, null, shutdownIntent,
16963                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16964                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16965                    }
16966                };
16967                // Kick things off.
16968                broadcastIntentLocked(null, null, stoppingIntent,
16969                        null, stoppingReceiver, 0, null, null,
16970                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16971                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16972            } finally {
16973                Binder.restoreCallingIdentity(ident);
16974            }
16975        }
16976
16977        return ActivityManager.USER_OP_SUCCESS;
16978    }
16979
16980    void finishUserStop(UserStartedState uss) {
16981        final int userId = uss.mHandle.getIdentifier();
16982        boolean stopped;
16983        ArrayList<IStopUserCallback> callbacks;
16984        synchronized (this) {
16985            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16986            if (mStartedUsers.get(userId) != uss) {
16987                stopped = false;
16988            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16989                stopped = false;
16990            } else {
16991                stopped = true;
16992                // User can no longer run.
16993                mStartedUsers.remove(userId);
16994                mUserLru.remove(Integer.valueOf(userId));
16995                updateStartedUserArrayLocked();
16996
16997                // Clean up all state and processes associated with the user.
16998                // Kill all the processes for the user.
16999                forceStopUserLocked(userId, "finish user");
17000            }
17001        }
17002
17003        for (int i=0; i<callbacks.size(); i++) {
17004            try {
17005                if (stopped) callbacks.get(i).userStopped(userId);
17006                else callbacks.get(i).userStopAborted(userId);
17007            } catch (RemoteException e) {
17008            }
17009        }
17010
17011        if (stopped) {
17012            mSystemServiceManager.cleanupUser(userId);
17013            synchronized (this) {
17014                mStackSupervisor.removeUserLocked(userId);
17015            }
17016        }
17017    }
17018
17019    @Override
17020    public UserInfo getCurrentUser() {
17021        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17022                != PackageManager.PERMISSION_GRANTED) && (
17023                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17024                != PackageManager.PERMISSION_GRANTED)) {
17025            String msg = "Permission Denial: getCurrentUser() from pid="
17026                    + Binder.getCallingPid()
17027                    + ", uid=" + Binder.getCallingUid()
17028                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17029            Slog.w(TAG, msg);
17030            throw new SecurityException(msg);
17031        }
17032        synchronized (this) {
17033            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17034        }
17035    }
17036
17037    int getCurrentUserIdLocked() {
17038        return mCurrentUserId;
17039    }
17040
17041    @Override
17042    public boolean isUserRunning(int userId, boolean orStopped) {
17043        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17044                != PackageManager.PERMISSION_GRANTED) {
17045            String msg = "Permission Denial: isUserRunning() from pid="
17046                    + Binder.getCallingPid()
17047                    + ", uid=" + Binder.getCallingUid()
17048                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17049            Slog.w(TAG, msg);
17050            throw new SecurityException(msg);
17051        }
17052        synchronized (this) {
17053            return isUserRunningLocked(userId, orStopped);
17054        }
17055    }
17056
17057    boolean isUserRunningLocked(int userId, boolean orStopped) {
17058        UserStartedState state = mStartedUsers.get(userId);
17059        if (state == null) {
17060            return false;
17061        }
17062        if (orStopped) {
17063            return true;
17064        }
17065        return state.mState != UserStartedState.STATE_STOPPING
17066                && state.mState != UserStartedState.STATE_SHUTDOWN;
17067    }
17068
17069    @Override
17070    public int[] getRunningUserIds() {
17071        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17072                != PackageManager.PERMISSION_GRANTED) {
17073            String msg = "Permission Denial: isUserRunning() from pid="
17074                    + Binder.getCallingPid()
17075                    + ", uid=" + Binder.getCallingUid()
17076                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17077            Slog.w(TAG, msg);
17078            throw new SecurityException(msg);
17079        }
17080        synchronized (this) {
17081            return mStartedUserArray;
17082        }
17083    }
17084
17085    private void updateStartedUserArrayLocked() {
17086        int num = 0;
17087        for (int i=0; i<mStartedUsers.size();  i++) {
17088            UserStartedState uss = mStartedUsers.valueAt(i);
17089            // This list does not include stopping users.
17090            if (uss.mState != UserStartedState.STATE_STOPPING
17091                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17092                num++;
17093            }
17094        }
17095        mStartedUserArray = new int[num];
17096        num = 0;
17097        for (int i=0; i<mStartedUsers.size();  i++) {
17098            UserStartedState uss = mStartedUsers.valueAt(i);
17099            if (uss.mState != UserStartedState.STATE_STOPPING
17100                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17101                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17102                num++;
17103            }
17104        }
17105    }
17106
17107    @Override
17108    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17109        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17110                != PackageManager.PERMISSION_GRANTED) {
17111            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17112                    + Binder.getCallingPid()
17113                    + ", uid=" + Binder.getCallingUid()
17114                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17115            Slog.w(TAG, msg);
17116            throw new SecurityException(msg);
17117        }
17118
17119        mUserSwitchObservers.register(observer);
17120    }
17121
17122    @Override
17123    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17124        mUserSwitchObservers.unregister(observer);
17125    }
17126
17127    private boolean userExists(int userId) {
17128        if (userId == 0) {
17129            return true;
17130        }
17131        UserManagerService ums = getUserManagerLocked();
17132        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17133    }
17134
17135    int[] getUsersLocked() {
17136        UserManagerService ums = getUserManagerLocked();
17137        return ums != null ? ums.getUserIds() : new int[] { 0 };
17138    }
17139
17140    UserManagerService getUserManagerLocked() {
17141        if (mUserManager == null) {
17142            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17143            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17144        }
17145        return mUserManager;
17146    }
17147
17148    private int applyUserId(int uid, int userId) {
17149        return UserHandle.getUid(userId, uid);
17150    }
17151
17152    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17153        if (info == null) return null;
17154        ApplicationInfo newInfo = new ApplicationInfo(info);
17155        newInfo.uid = applyUserId(info.uid, userId);
17156        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17157                + info.packageName;
17158        return newInfo;
17159    }
17160
17161    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17162        if (aInfo == null
17163                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17164            return aInfo;
17165        }
17166
17167        ActivityInfo info = new ActivityInfo(aInfo);
17168        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17169        return info;
17170    }
17171
17172    private final class LocalService extends ActivityManagerInternal {
17173        @Override
17174        public void goingToSleep() {
17175            ActivityManagerService.this.goingToSleep();
17176        }
17177
17178        @Override
17179        public void wakingUp() {
17180            ActivityManagerService.this.wakingUp();
17181        }
17182    }
17183
17184    /**
17185     * An implementation of IAppTask, that allows an app to manage its own tasks via
17186     * {@link android.app.ActivityManager#AppTask}.  We keep track of the callingUid to ensure that
17187     * only the process that calls getAppTasks() can call the AppTask methods.
17188     */
17189    class AppTaskImpl extends IAppTask.Stub {
17190        private int mTaskId;
17191        private int mCallingUid;
17192
17193        public AppTaskImpl(int taskId, int callingUid) {
17194            mTaskId = taskId;
17195            mCallingUid = callingUid;
17196        }
17197
17198        @Override
17199        public void finishAndRemoveTask() {
17200            // Ensure that we are called from the same process that created this AppTask
17201            if (mCallingUid != Binder.getCallingUid()) {
17202                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17203                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17204                return;
17205            }
17206
17207            synchronized (ActivityManagerService.this) {
17208                long origId = Binder.clearCallingIdentity();
17209                try {
17210                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17211                    if (tr != null) {
17212                        // Only kill the process if we are not a new document
17213                        int flags = tr.getBaseIntent().getFlags();
17214                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17215                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17216                        removeTaskByIdLocked(mTaskId,
17217                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17218                    }
17219                } finally {
17220                    Binder.restoreCallingIdentity(origId);
17221                }
17222            }
17223        }
17224
17225        @Override
17226        public ActivityManager.RecentTaskInfo getTaskInfo() {
17227            // Ensure that we are called from the same process that created this AppTask
17228            if (mCallingUid != Binder.getCallingUid()) {
17229                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17230                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17231                return null;
17232            }
17233
17234            synchronized (ActivityManagerService.this) {
17235                long origId = Binder.clearCallingIdentity();
17236                try {
17237                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17238                    if (tr != null) {
17239                        return createRecentTaskInfoFromTaskRecord(tr);
17240                    }
17241                } finally {
17242                    Binder.restoreCallingIdentity(origId);
17243                }
17244                return null;
17245            }
17246        }
17247    }
17248}
17249