ActivityManagerService.java revision 87f851d0bad0183eccbb59b1fb378db9155e4a66
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    ArrayList<TaskRecord> mRecentTasks;
413
414    public class PendingAssistExtras extends Binder implements Runnable {
415        public final ActivityRecord activity;
416        public boolean haveResult = false;
417        public Bundle result = null;
418        public PendingAssistExtras(ActivityRecord _activity) {
419            activity = _activity;
420        }
421        @Override
422        public void run() {
423            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
424            synchronized (this) {
425                haveResult = true;
426                notifyAll();
427            }
428        }
429    }
430
431    final ArrayList<PendingAssistExtras> mPendingAssistExtras
432            = new ArrayList<PendingAssistExtras>();
433
434    /**
435     * Process management.
436     */
437    final ProcessList mProcessList = new ProcessList();
438
439    /**
440     * All of the applications we currently have running organized by name.
441     * The keys are strings of the application package name (as
442     * returned by the package manager), and the keys are ApplicationRecord
443     * objects.
444     */
445    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
446
447    /**
448     * Tracking long-term execution of processes to look for abuse and other
449     * bad app behavior.
450     */
451    final ProcessStatsService mProcessStats;
452
453    /**
454     * The currently running isolated processes.
455     */
456    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
457
458    /**
459     * Counter for assigning isolated process uids, to avoid frequently reusing the
460     * same ones.
461     */
462    int mNextIsolatedProcessUid = 0;
463
464    /**
465     * The currently running heavy-weight process, if any.
466     */
467    ProcessRecord mHeavyWeightProcess = null;
468
469    /**
470     * The last time that various processes have crashed.
471     */
472    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
473
474    /**
475     * Information about a process that is currently marked as bad.
476     */
477    static final class BadProcessInfo {
478        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
479            this.time = time;
480            this.shortMsg = shortMsg;
481            this.longMsg = longMsg;
482            this.stack = stack;
483        }
484
485        final long time;
486        final String shortMsg;
487        final String longMsg;
488        final String stack;
489    }
490
491    /**
492     * Set of applications that we consider to be bad, and will reject
493     * incoming broadcasts from (which the user has no control over).
494     * Processes are added to this set when they have crashed twice within
495     * a minimum amount of time; they are removed from it when they are
496     * later restarted (hopefully due to some user action).  The value is the
497     * time it was added to the list.
498     */
499    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
500
501    /**
502     * All of the processes we currently have running organized by pid.
503     * The keys are the pid running the application.
504     *
505     * <p>NOTE: This object is protected by its own lock, NOT the global
506     * activity manager lock!
507     */
508    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
509
510    /**
511     * All of the processes that have been forced to be foreground.  The key
512     * is the pid of the caller who requested it (we hold a death
513     * link on it).
514     */
515    abstract class ForegroundToken implements IBinder.DeathRecipient {
516        int pid;
517        IBinder token;
518    }
519    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
520
521    /**
522     * List of records for processes that someone had tried to start before the
523     * system was ready.  We don't start them at that point, but ensure they
524     * are started by the time booting is complete.
525     */
526    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
527
528    /**
529     * List of persistent applications that are in the process
530     * of being started.
531     */
532    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
533
534    /**
535     * Processes that are being forcibly torn down.
536     */
537    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
538
539    /**
540     * List of running applications, sorted by recent usage.
541     * The first entry in the list is the least recently used.
542     */
543    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
544
545    /**
546     * Where in mLruProcesses that the processes hosting activities start.
547     */
548    int mLruProcessActivityStart = 0;
549
550    /**
551     * Where in mLruProcesses that the processes hosting services start.
552     * This is after (lower index) than mLruProcessesActivityStart.
553     */
554    int mLruProcessServiceStart = 0;
555
556    /**
557     * List of processes that should gc as soon as things are idle.
558     */
559    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
560
561    /**
562     * Processes we want to collect PSS data from.
563     */
564    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Last time we requested PSS data of all processes.
568     */
569    long mLastFullPssTime = SystemClock.uptimeMillis();
570
571    /**
572     * This is the process holding what we currently consider to be
573     * the "home" activity.
574     */
575    ProcessRecord mHomeProcess;
576
577    /**
578     * This is the process holding the activity the user last visited that
579     * is in a different process from the one they are currently in.
580     */
581    ProcessRecord mPreviousProcess;
582
583    /**
584     * The time at which the previous process was last visible.
585     */
586    long mPreviousProcessVisibleTime;
587
588    /**
589     * Which uses have been started, so are allowed to run code.
590     */
591    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
592
593    /**
594     * LRU list of history of current users.  Most recently current is at the end.
595     */
596    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
597
598    /**
599     * Constant array of the users that are currently started.
600     */
601    int[] mStartedUserArray = new int[] { 0 };
602
603    /**
604     * Registered observers of the user switching mechanics.
605     */
606    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
607            = new RemoteCallbackList<IUserSwitchObserver>();
608
609    /**
610     * Currently active user switch.
611     */
612    Object mCurUserSwitchCallback;
613
614    /**
615     * Packages that the user has asked to have run in screen size
616     * compatibility mode instead of filling the screen.
617     */
618    final CompatModePackages mCompatModePackages;
619
620    /**
621     * Set of IntentSenderRecord objects that are currently active.
622     */
623    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
624            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
625
626    /**
627     * Fingerprints (hashCode()) of stack traces that we've
628     * already logged DropBox entries for.  Guarded by itself.  If
629     * something (rogue user app) forces this over
630     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
631     */
632    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
633    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
634
635    /**
636     * Strict Mode background batched logging state.
637     *
638     * The string buffer is guarded by itself, and its lock is also
639     * used to determine if another batched write is already
640     * in-flight.
641     */
642    private final StringBuilder mStrictModeBuffer = new StringBuilder();
643
644    /**
645     * Keeps track of all IIntentReceivers that have been registered for
646     * broadcasts.  Hash keys are the receiver IBinder, hash value is
647     * a ReceiverList.
648     */
649    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
650            new HashMap<IBinder, ReceiverList>();
651
652    /**
653     * Resolver for broadcast intents to registered receivers.
654     * Holds BroadcastFilter (subclass of IntentFilter).
655     */
656    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
657            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
658        @Override
659        protected boolean allowFilterResult(
660                BroadcastFilter filter, List<BroadcastFilter> dest) {
661            IBinder target = filter.receiverList.receiver.asBinder();
662            for (int i=dest.size()-1; i>=0; i--) {
663                if (dest.get(i).receiverList.receiver.asBinder() == target) {
664                    return false;
665                }
666            }
667            return true;
668        }
669
670        @Override
671        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
672            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
673                    || userId == filter.owningUserId) {
674                return super.newResult(filter, match, userId);
675            }
676            return null;
677        }
678
679        @Override
680        protected BroadcastFilter[] newArray(int size) {
681            return new BroadcastFilter[size];
682        }
683
684        @Override
685        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
686            return packageName.equals(filter.packageName);
687        }
688    };
689
690    /**
691     * State of all active sticky broadcasts per user.  Keys are the action of the
692     * sticky Intent, values are an ArrayList of all broadcasted intents with
693     * that action (which should usually be one).  The SparseArray is keyed
694     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
695     * for stickies that are sent to all users.
696     */
697    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
698            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
699
700    final ActiveServices mServices;
701
702    /**
703     * Backup/restore process management
704     */
705    String mBackupAppName = null;
706    BackupRecord mBackupTarget = null;
707
708    final ProviderMap mProviderMap;
709
710    /**
711     * List of content providers who have clients waiting for them.  The
712     * application is currently being launched and the provider will be
713     * removed from this list once it is published.
714     */
715    final ArrayList<ContentProviderRecord> mLaunchingProviders
716            = new ArrayList<ContentProviderRecord>();
717
718    /**
719     * File storing persisted {@link #mGrantedUriPermissions}.
720     */
721    private final AtomicFile mGrantFile;
722
723    /** XML constants used in {@link #mGrantFile} */
724    private static final String TAG_URI_GRANTS = "uri-grants";
725    private static final String TAG_URI_GRANT = "uri-grant";
726    private static final String ATTR_USER_HANDLE = "userHandle";
727    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
728    private static final String ATTR_TARGET_USER_ID = "targetUserId";
729    private static final String ATTR_SOURCE_PKG = "sourcePkg";
730    private static final String ATTR_TARGET_PKG = "targetPkg";
731    private static final String ATTR_URI = "uri";
732    private static final String ATTR_MODE_FLAGS = "modeFlags";
733    private static final String ATTR_CREATED_TIME = "createdTime";
734    private static final String ATTR_PREFIX = "prefix";
735
736    /**
737     * Global set of specific {@link Uri} permissions that have been granted.
738     * This optimized lookup structure maps from {@link UriPermission#targetUid}
739     * to {@link UriPermission#uri} to {@link UriPermission}.
740     */
741    @GuardedBy("this")
742    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
743            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
744
745    public static class GrantUri {
746        public final int sourceUserId;
747        public final Uri uri;
748        public boolean prefix;
749
750        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
751            this.sourceUserId = sourceUserId;
752            this.uri = uri;
753            this.prefix = prefix;
754        }
755
756        @Override
757        public int hashCode() {
758            return toString().hashCode();
759        }
760
761        @Override
762        public boolean equals(Object o) {
763            if (o instanceof GrantUri) {
764                GrantUri other = (GrantUri) o;
765                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
766                        && prefix == other.prefix;
767            }
768            return false;
769        }
770
771        @Override
772        public String toString() {
773            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
774            if (prefix) result += " [prefix]";
775            return result;
776        }
777
778        public String toSafeString() {
779            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
780            if (prefix) result += " [prefix]";
781            return result;
782        }
783
784        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
785            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
786                    ContentProvider.getUriWithoutUserId(uri), false);
787        }
788    }
789
790    CoreSettingsObserver mCoreSettingsObserver;
791
792    /**
793     * Thread-local storage used to carry caller permissions over through
794     * indirect content-provider access.
795     */
796    private class Identity {
797        public int pid;
798        public int uid;
799
800        Identity(int _pid, int _uid) {
801            pid = _pid;
802            uid = _uid;
803        }
804    }
805
806    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
807
808    /**
809     * All information we have collected about the runtime performance of
810     * any user id that can impact battery performance.
811     */
812    final BatteryStatsService mBatteryStatsService;
813
814    /**
815     * Information about component usage
816     */
817    final UsageStatsService mUsageStatsService;
818
819    /**
820     * Information about and control over application operations
821     */
822    final AppOpsService mAppOpsService;
823
824    /**
825     * Save recent tasks information across reboots.
826     */
827    final TaskPersister mTaskPersister;
828
829    /**
830     * Current configuration information.  HistoryRecord objects are given
831     * a reference to this object to indicate which configuration they are
832     * currently running in, so this object must be kept immutable.
833     */
834    Configuration mConfiguration = new Configuration();
835
836    /**
837     * Current sequencing integer of the configuration, for skipping old
838     * configurations.
839     */
840    int mConfigurationSeq = 0;
841
842    /**
843     * Hardware-reported OpenGLES version.
844     */
845    final int GL_ES_VERSION;
846
847    /**
848     * List of initialization arguments to pass to all processes when binding applications to them.
849     * For example, references to the commonly used services.
850     */
851    HashMap<String, IBinder> mAppBindArgs;
852
853    /**
854     * Temporary to avoid allocations.  Protected by main lock.
855     */
856    final StringBuilder mStringBuilder = new StringBuilder(256);
857
858    /**
859     * Used to control how we initialize the service.
860     */
861    ComponentName mTopComponent;
862    String mTopAction = Intent.ACTION_MAIN;
863    String mTopData;
864    boolean mProcessesReady = false;
865    boolean mSystemReady = false;
866    boolean mBooting = false;
867    boolean mWaitingUpdate = false;
868    boolean mDidUpdate = false;
869    boolean mOnBattery = false;
870    boolean mLaunchWarningShown = false;
871
872    Context mContext;
873
874    int mFactoryTest;
875
876    boolean mCheckedForSetup;
877
878    /**
879     * The time at which we will allow normal application switches again,
880     * after a call to {@link #stopAppSwitches()}.
881     */
882    long mAppSwitchesAllowedTime;
883
884    /**
885     * This is set to true after the first switch after mAppSwitchesAllowedTime
886     * is set; any switches after that will clear the time.
887     */
888    boolean mDidAppSwitch;
889
890    /**
891     * Last time (in realtime) at which we checked for power usage.
892     */
893    long mLastPowerCheckRealtime;
894
895    /**
896     * Last time (in uptime) at which we checked for power usage.
897     */
898    long mLastPowerCheckUptime;
899
900    /**
901     * Set while we are wanting to sleep, to prevent any
902     * activities from being started/resumed.
903     */
904    private boolean mSleeping = false;
905
906    /**
907     * Set while we are running a voice interaction.  This overrides
908     * sleeping while it is active.
909     */
910    private boolean mRunningVoice = false;
911
912    /**
913     * State of external calls telling us if the device is asleep.
914     */
915    private boolean mWentToSleep = false;
916
917    /**
918     * State of external call telling us if the lock screen is shown.
919     */
920    private boolean mLockScreenShown = false;
921
922    /**
923     * Set if we are shutting down the system, similar to sleeping.
924     */
925    boolean mShuttingDown = false;
926
927    /**
928     * Current sequence id for oom_adj computation traversal.
929     */
930    int mAdjSeq = 0;
931
932    /**
933     * Current sequence id for process LRU updating.
934     */
935    int mLruSeq = 0;
936
937    /**
938     * Keep track of the non-cached/empty process we last found, to help
939     * determine how to distribute cached/empty processes next time.
940     */
941    int mNumNonCachedProcs = 0;
942
943    /**
944     * Keep track of the number of cached hidden procs, to balance oom adj
945     * distribution between those and empty procs.
946     */
947    int mNumCachedHiddenProcs = 0;
948
949    /**
950     * Keep track of the number of service processes we last found, to
951     * determine on the next iteration which should be B services.
952     */
953    int mNumServiceProcs = 0;
954    int mNewNumAServiceProcs = 0;
955    int mNewNumServiceProcs = 0;
956
957    /**
958     * Allow the current computed overall memory level of the system to go down?
959     * This is set to false when we are killing processes for reasons other than
960     * memory management, so that the now smaller process list will not be taken as
961     * an indication that memory is tighter.
962     */
963    boolean mAllowLowerMemLevel = false;
964
965    /**
966     * The last computed memory level, for holding when we are in a state that
967     * processes are going away for other reasons.
968     */
969    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
970
971    /**
972     * The last total number of process we have, to determine if changes actually look
973     * like a shrinking number of process due to lower RAM.
974     */
975    int mLastNumProcesses;
976
977    /**
978     * The uptime of the last time we performed idle maintenance.
979     */
980    long mLastIdleTime = SystemClock.uptimeMillis();
981
982    /**
983     * Total time spent with RAM that has been added in the past since the last idle time.
984     */
985    long mLowRamTimeSinceLastIdle = 0;
986
987    /**
988     * If RAM is currently low, when that horrible situation started.
989     */
990    long mLowRamStartTime = 0;
991
992    /**
993     * For reporting to battery stats the current top application.
994     */
995    private String mCurResumedPackage = null;
996    private int mCurResumedUid = -1;
997
998    /**
999     * For reporting to battery stats the apps currently running foreground
1000     * service.  The ProcessMap is package/uid tuples; each of these contain
1001     * an array of the currently foreground processes.
1002     */
1003    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1004            = new ProcessMap<ArrayList<ProcessRecord>>();
1005
1006    /**
1007     * This is set if we had to do a delayed dexopt of an app before launching
1008     * it, to increase the ANR timeouts in that case.
1009     */
1010    boolean mDidDexOpt;
1011
1012    /**
1013     * Set if the systemServer made a call to enterSafeMode.
1014     */
1015    boolean mSafeMode;
1016
1017    String mDebugApp = null;
1018    boolean mWaitForDebugger = false;
1019    boolean mDebugTransient = false;
1020    String mOrigDebugApp = null;
1021    boolean mOrigWaitForDebugger = false;
1022    boolean mAlwaysFinishActivities = false;
1023    IActivityController mController = null;
1024    String mProfileApp = null;
1025    ProcessRecord mProfileProc = null;
1026    String mProfileFile;
1027    ParcelFileDescriptor mProfileFd;
1028    int mProfileType = 0;
1029    boolean mAutoStopProfiler = false;
1030    String mOpenGlTraceApp = null;
1031
1032    static class ProcessChangeItem {
1033        static final int CHANGE_ACTIVITIES = 1<<0;
1034        static final int CHANGE_PROCESS_STATE = 1<<1;
1035        int changes;
1036        int uid;
1037        int pid;
1038        int processState;
1039        boolean foregroundActivities;
1040    }
1041
1042    final RemoteCallbackList<IProcessObserver> mProcessObservers
1043            = new RemoteCallbackList<IProcessObserver>();
1044    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1045
1046    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1047            = new ArrayList<ProcessChangeItem>();
1048    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1049            = new ArrayList<ProcessChangeItem>();
1050
1051    /**
1052     * Runtime CPU use collection thread.  This object's lock is used to
1053     * protect all related state.
1054     */
1055    final Thread mProcessCpuThread;
1056
1057    /**
1058     * Used to collect process stats when showing not responding dialog.
1059     * Protected by mProcessCpuThread.
1060     */
1061    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1062            MONITOR_THREAD_CPU_USAGE);
1063    final AtomicLong mLastCpuTime = new AtomicLong(0);
1064    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1065
1066    long mLastWriteTime = 0;
1067
1068    /**
1069     * Used to retain an update lock when the foreground activity is in
1070     * immersive mode.
1071     */
1072    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1073
1074    /**
1075     * Set to true after the system has finished booting.
1076     */
1077    boolean mBooted = false;
1078
1079    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1080    int mProcessLimitOverride = -1;
1081
1082    WindowManagerService mWindowManager;
1083
1084    final ActivityThread mSystemThread;
1085
1086    int mCurrentUserId = 0;
1087    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1088    private UserManagerService mUserManager;
1089
1090    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1091        final ProcessRecord mApp;
1092        final int mPid;
1093        final IApplicationThread mAppThread;
1094
1095        AppDeathRecipient(ProcessRecord app, int pid,
1096                IApplicationThread thread) {
1097            if (localLOGV) Slog.v(
1098                TAG, "New death recipient " + this
1099                + " for thread " + thread.asBinder());
1100            mApp = app;
1101            mPid = pid;
1102            mAppThread = thread;
1103        }
1104
1105        @Override
1106        public void binderDied() {
1107            if (localLOGV) Slog.v(
1108                TAG, "Death received in " + this
1109                + " for thread " + mAppThread.asBinder());
1110            synchronized(ActivityManagerService.this) {
1111                appDiedLocked(mApp, mPid, mAppThread);
1112            }
1113        }
1114    }
1115
1116    static final int SHOW_ERROR_MSG = 1;
1117    static final int SHOW_NOT_RESPONDING_MSG = 2;
1118    static final int SHOW_FACTORY_ERROR_MSG = 3;
1119    static final int UPDATE_CONFIGURATION_MSG = 4;
1120    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1121    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1122    static final int SERVICE_TIMEOUT_MSG = 12;
1123    static final int UPDATE_TIME_ZONE = 13;
1124    static final int SHOW_UID_ERROR_MSG = 14;
1125    static final int IM_FEELING_LUCKY_MSG = 15;
1126    static final int PROC_START_TIMEOUT_MSG = 20;
1127    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1128    static final int KILL_APPLICATION_MSG = 22;
1129    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1130    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1131    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1132    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1133    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1134    static final int CLEAR_DNS_CACHE_MSG = 28;
1135    static final int UPDATE_HTTP_PROXY_MSG = 29;
1136    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1137    static final int DISPATCH_PROCESSES_CHANGED = 31;
1138    static final int DISPATCH_PROCESS_DIED = 32;
1139    static final int REPORT_MEM_USAGE_MSG = 33;
1140    static final int REPORT_USER_SWITCH_MSG = 34;
1141    static final int CONTINUE_USER_SWITCH_MSG = 35;
1142    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1143    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1144    static final int PERSIST_URI_GRANTS_MSG = 38;
1145    static final int REQUEST_ALL_PSS_MSG = 39;
1146    static final int START_PROFILES_MSG = 40;
1147    static final int UPDATE_TIME = 41;
1148    static final int SYSTEM_USER_START_MSG = 42;
1149    static final int SYSTEM_USER_CURRENT_MSG = 43;
1150
1151    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1152    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1153    static final int FIRST_COMPAT_MODE_MSG = 300;
1154    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1155
1156    AlertDialog mUidAlert;
1157    CompatModeDialog mCompatModeDialog;
1158    long mLastMemUsageReportTime = 0;
1159
1160    /**
1161     * Flag whether the current user is a "monkey", i.e. whether
1162     * the UI is driven by a UI automation tool.
1163     */
1164    private boolean mUserIsMonkey;
1165
1166    final ServiceThread mHandlerThread;
1167    final MainHandler mHandler;
1168
1169    final class MainHandler extends Handler {
1170        public MainHandler(Looper looper) {
1171            super(looper, null, true);
1172        }
1173
1174        @Override
1175        public void handleMessage(Message msg) {
1176            switch (msg.what) {
1177            case SHOW_ERROR_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1180                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1181                synchronized (ActivityManagerService.this) {
1182                    ProcessRecord proc = (ProcessRecord)data.get("app");
1183                    AppErrorResult res = (AppErrorResult) data.get("result");
1184                    if (proc != null && proc.crashDialog != null) {
1185                        Slog.e(TAG, "App already has crash dialog: " + proc);
1186                        if (res != null) {
1187                            res.set(0);
1188                        }
1189                        return;
1190                    }
1191                    if (!showBackground && UserHandle.getAppId(proc.uid)
1192                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1193                            && proc.pid != MY_PID) {
1194                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1195                        if (res != null) {
1196                            res.set(0);
1197                        }
1198                        return;
1199                    }
1200                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1201                        Dialog d = new AppErrorDialog(mContext,
1202                                ActivityManagerService.this, res, proc);
1203                        d.show();
1204                        proc.crashDialog = d;
1205                    } else {
1206                        // The device is asleep, so just pretend that the user
1207                        // saw a crash dialog and hit "force quit".
1208                        if (res != null) {
1209                            res.set(0);
1210                        }
1211                    }
1212                }
1213
1214                ensureBootCompleted();
1215            } break;
1216            case SHOW_NOT_RESPONDING_MSG: {
1217                synchronized (ActivityManagerService.this) {
1218                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1219                    ProcessRecord proc = (ProcessRecord)data.get("app");
1220                    if (proc != null && proc.anrDialog != null) {
1221                        Slog.e(TAG, "App already has anr dialog: " + proc);
1222                        return;
1223                    }
1224
1225                    Intent intent = new Intent("android.intent.action.ANR");
1226                    if (!mProcessesReady) {
1227                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1228                                | Intent.FLAG_RECEIVER_FOREGROUND);
1229                    }
1230                    broadcastIntentLocked(null, null, intent,
1231                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1232                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1233
1234                    if (mShowDialogs) {
1235                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1236                                mContext, proc, (ActivityRecord)data.get("activity"),
1237                                msg.arg1 != 0);
1238                        d.show();
1239                        proc.anrDialog = d;
1240                    } else {
1241                        // Just kill the app if there is no dialog to be shown.
1242                        killAppAtUsersRequest(proc, null);
1243                    }
1244                }
1245
1246                ensureBootCompleted();
1247            } break;
1248            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1249                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1250                synchronized (ActivityManagerService.this) {
1251                    ProcessRecord proc = (ProcessRecord) data.get("app");
1252                    if (proc == null) {
1253                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1254                        break;
1255                    }
1256                    if (proc.crashDialog != null) {
1257                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1258                        return;
1259                    }
1260                    AppErrorResult res = (AppErrorResult) data.get("result");
1261                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1262                        Dialog d = new StrictModeViolationDialog(mContext,
1263                                ActivityManagerService.this, res, proc);
1264                        d.show();
1265                        proc.crashDialog = d;
1266                    } else {
1267                        // The device is asleep, so just pretend that the user
1268                        // saw a crash dialog and hit "force quit".
1269                        res.set(0);
1270                    }
1271                }
1272                ensureBootCompleted();
1273            } break;
1274            case SHOW_FACTORY_ERROR_MSG: {
1275                Dialog d = new FactoryErrorDialog(
1276                    mContext, msg.getData().getCharSequence("msg"));
1277                d.show();
1278                ensureBootCompleted();
1279            } break;
1280            case UPDATE_CONFIGURATION_MSG: {
1281                final ContentResolver resolver = mContext.getContentResolver();
1282                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1283            } break;
1284            case GC_BACKGROUND_PROCESSES_MSG: {
1285                synchronized (ActivityManagerService.this) {
1286                    performAppGcsIfAppropriateLocked();
1287                }
1288            } break;
1289            case WAIT_FOR_DEBUGGER_MSG: {
1290                synchronized (ActivityManagerService.this) {
1291                    ProcessRecord app = (ProcessRecord)msg.obj;
1292                    if (msg.arg1 != 0) {
1293                        if (!app.waitedForDebugger) {
1294                            Dialog d = new AppWaitingForDebuggerDialog(
1295                                    ActivityManagerService.this,
1296                                    mContext, app);
1297                            app.waitDialog = d;
1298                            app.waitedForDebugger = true;
1299                            d.show();
1300                        }
1301                    } else {
1302                        if (app.waitDialog != null) {
1303                            app.waitDialog.dismiss();
1304                            app.waitDialog = null;
1305                        }
1306                    }
1307                }
1308            } break;
1309            case SERVICE_TIMEOUT_MSG: {
1310                if (mDidDexOpt) {
1311                    mDidDexOpt = false;
1312                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1313                    nmsg.obj = msg.obj;
1314                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1315                    return;
1316                }
1317                mServices.serviceTimeout((ProcessRecord)msg.obj);
1318            } break;
1319            case UPDATE_TIME_ZONE: {
1320                synchronized (ActivityManagerService.this) {
1321                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1322                        ProcessRecord r = mLruProcesses.get(i);
1323                        if (r.thread != null) {
1324                            try {
1325                                r.thread.updateTimeZone();
1326                            } catch (RemoteException ex) {
1327                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1328                            }
1329                        }
1330                    }
1331                }
1332            } break;
1333            case CLEAR_DNS_CACHE_MSG: {
1334                synchronized (ActivityManagerService.this) {
1335                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1336                        ProcessRecord r = mLruProcesses.get(i);
1337                        if (r.thread != null) {
1338                            try {
1339                                r.thread.clearDnsCache();
1340                            } catch (RemoteException ex) {
1341                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1342                            }
1343                        }
1344                    }
1345                }
1346            } break;
1347            case UPDATE_HTTP_PROXY_MSG: {
1348                ProxyInfo proxy = (ProxyInfo)msg.obj;
1349                String host = "";
1350                String port = "";
1351                String exclList = "";
1352                Uri pacFileUrl = Uri.EMPTY;
1353                if (proxy != null) {
1354                    host = proxy.getHost();
1355                    port = Integer.toString(proxy.getPort());
1356                    exclList = proxy.getExclusionListAsString();
1357                    pacFileUrl = proxy.getPacFileUrl();
1358                }
1359                synchronized (ActivityManagerService.this) {
1360                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1361                        ProcessRecord r = mLruProcesses.get(i);
1362                        if (r.thread != null) {
1363                            try {
1364                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1365                            } catch (RemoteException ex) {
1366                                Slog.w(TAG, "Failed to update http proxy for: " +
1367                                        r.info.processName);
1368                            }
1369                        }
1370                    }
1371                }
1372            } break;
1373            case SHOW_UID_ERROR_MSG: {
1374                String title = "System UIDs Inconsistent";
1375                String text = "UIDs on the system are inconsistent, you need to wipe your"
1376                        + " data partition or your device will be unstable.";
1377                Log.e(TAG, title + ": " + text);
1378                if (mShowDialogs) {
1379                    // XXX This is a temporary dialog, no need to localize.
1380                    AlertDialog d = new BaseErrorDialog(mContext);
1381                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1382                    d.setCancelable(false);
1383                    d.setTitle(title);
1384                    d.setMessage(text);
1385                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1386                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1387                    mUidAlert = d;
1388                    d.show();
1389                }
1390            } break;
1391            case IM_FEELING_LUCKY_MSG: {
1392                if (mUidAlert != null) {
1393                    mUidAlert.dismiss();
1394                    mUidAlert = null;
1395                }
1396            } break;
1397            case PROC_START_TIMEOUT_MSG: {
1398                if (mDidDexOpt) {
1399                    mDidDexOpt = false;
1400                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1401                    nmsg.obj = msg.obj;
1402                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1403                    return;
1404                }
1405                ProcessRecord app = (ProcessRecord)msg.obj;
1406                synchronized (ActivityManagerService.this) {
1407                    processStartTimedOutLocked(app);
1408                }
1409            } break;
1410            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    doPendingActivityLaunchesLocked(true);
1413                }
1414            } break;
1415            case KILL_APPLICATION_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    int appid = msg.arg1;
1418                    boolean restart = (msg.arg2 == 1);
1419                    Bundle bundle = (Bundle)msg.obj;
1420                    String pkg = bundle.getString("pkg");
1421                    String reason = bundle.getString("reason");
1422                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1423                            false, UserHandle.USER_ALL, reason);
1424                }
1425            } break;
1426            case FINALIZE_PENDING_INTENT_MSG: {
1427                ((PendingIntentRecord)msg.obj).completeFinalize();
1428            } break;
1429            case POST_HEAVY_NOTIFICATION_MSG: {
1430                INotificationManager inm = NotificationManager.getService();
1431                if (inm == null) {
1432                    return;
1433                }
1434
1435                ActivityRecord root = (ActivityRecord)msg.obj;
1436                ProcessRecord process = root.app;
1437                if (process == null) {
1438                    return;
1439                }
1440
1441                try {
1442                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1443                    String text = mContext.getString(R.string.heavy_weight_notification,
1444                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1445                    Notification notification = new Notification();
1446                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1447                    notification.when = 0;
1448                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1449                    notification.tickerText = text;
1450                    notification.defaults = 0; // please be quiet
1451                    notification.sound = null;
1452                    notification.vibrate = null;
1453                    notification.setLatestEventInfo(context, text,
1454                            mContext.getText(R.string.heavy_weight_notification_detail),
1455                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1456                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1457                                    new UserHandle(root.userId)));
1458
1459                    try {
1460                        int[] outId = new int[1];
1461                        inm.enqueueNotificationWithTag("android", "android", null,
1462                                R.string.heavy_weight_notification,
1463                                notification, outId, root.userId);
1464                    } catch (RuntimeException e) {
1465                        Slog.w(ActivityManagerService.TAG,
1466                                "Error showing notification for heavy-weight app", e);
1467                    } catch (RemoteException e) {
1468                    }
1469                } catch (NameNotFoundException e) {
1470                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1471                }
1472            } break;
1473            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1474                INotificationManager inm = NotificationManager.getService();
1475                if (inm == null) {
1476                    return;
1477                }
1478                try {
1479                    inm.cancelNotificationWithTag("android", null,
1480                            R.string.heavy_weight_notification,  msg.arg1);
1481                } catch (RuntimeException e) {
1482                    Slog.w(ActivityManagerService.TAG,
1483                            "Error canceling notification for service", e);
1484                } catch (RemoteException e) {
1485                }
1486            } break;
1487            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1488                synchronized (ActivityManagerService.this) {
1489                    checkExcessivePowerUsageLocked(true);
1490                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1491                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1492                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1493                }
1494            } break;
1495            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1496                synchronized (ActivityManagerService.this) {
1497                    ActivityRecord ar = (ActivityRecord)msg.obj;
1498                    if (mCompatModeDialog != null) {
1499                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1500                                ar.info.applicationInfo.packageName)) {
1501                            return;
1502                        }
1503                        mCompatModeDialog.dismiss();
1504                        mCompatModeDialog = null;
1505                    }
1506                    if (ar != null && false) {
1507                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1508                                ar.packageName)) {
1509                            int mode = mCompatModePackages.computeCompatModeLocked(
1510                                    ar.info.applicationInfo);
1511                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1512                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1513                                mCompatModeDialog = new CompatModeDialog(
1514                                        ActivityManagerService.this, mContext,
1515                                        ar.info.applicationInfo);
1516                                mCompatModeDialog.show();
1517                            }
1518                        }
1519                    }
1520                }
1521                break;
1522            }
1523            case DISPATCH_PROCESSES_CHANGED: {
1524                dispatchProcessesChanged();
1525                break;
1526            }
1527            case DISPATCH_PROCESS_DIED: {
1528                final int pid = msg.arg1;
1529                final int uid = msg.arg2;
1530                dispatchProcessDied(pid, uid);
1531                break;
1532            }
1533            case REPORT_MEM_USAGE_MSG: {
1534                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1535                Thread thread = new Thread() {
1536                    @Override public void run() {
1537                        final SparseArray<ProcessMemInfo> infoMap
1538                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1539                        for (int i=0, N=memInfos.size(); i<N; i++) {
1540                            ProcessMemInfo mi = memInfos.get(i);
1541                            infoMap.put(mi.pid, mi);
1542                        }
1543                        updateCpuStatsNow();
1544                        synchronized (mProcessCpuThread) {
1545                            final int N = mProcessCpuTracker.countStats();
1546                            for (int i=0; i<N; i++) {
1547                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1548                                if (st.vsize > 0) {
1549                                    long pss = Debug.getPss(st.pid, null);
1550                                    if (pss > 0) {
1551                                        if (infoMap.indexOfKey(st.pid) < 0) {
1552                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1553                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1554                                            mi.pss = pss;
1555                                            memInfos.add(mi);
1556                                        }
1557                                    }
1558                                }
1559                            }
1560                        }
1561
1562                        long totalPss = 0;
1563                        for (int i=0, N=memInfos.size(); i<N; i++) {
1564                            ProcessMemInfo mi = memInfos.get(i);
1565                            if (mi.pss == 0) {
1566                                mi.pss = Debug.getPss(mi.pid, null);
1567                            }
1568                            totalPss += mi.pss;
1569                        }
1570                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1571                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1572                                if (lhs.oomAdj != rhs.oomAdj) {
1573                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1574                                }
1575                                if (lhs.pss != rhs.pss) {
1576                                    return lhs.pss < rhs.pss ? 1 : -1;
1577                                }
1578                                return 0;
1579                            }
1580                        });
1581
1582                        StringBuilder tag = new StringBuilder(128);
1583                        StringBuilder stack = new StringBuilder(128);
1584                        tag.append("Low on memory -- ");
1585                        appendMemBucket(tag, totalPss, "total", false);
1586                        appendMemBucket(stack, totalPss, "total", true);
1587
1588                        StringBuilder logBuilder = new StringBuilder(1024);
1589                        logBuilder.append("Low on memory:\n");
1590
1591                        boolean firstLine = true;
1592                        int lastOomAdj = Integer.MIN_VALUE;
1593                        for (int i=0, N=memInfos.size(); i<N; i++) {
1594                            ProcessMemInfo mi = memInfos.get(i);
1595
1596                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1597                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1598                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1599                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1600                                if (lastOomAdj != mi.oomAdj) {
1601                                    lastOomAdj = mi.oomAdj;
1602                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1603                                        tag.append(" / ");
1604                                    }
1605                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1606                                        if (firstLine) {
1607                                            stack.append(":");
1608                                            firstLine = false;
1609                                        }
1610                                        stack.append("\n\t at ");
1611                                    } else {
1612                                        stack.append("$");
1613                                    }
1614                                } else {
1615                                    tag.append(" ");
1616                                    stack.append("$");
1617                                }
1618                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1619                                    appendMemBucket(tag, mi.pss, mi.name, false);
1620                                }
1621                                appendMemBucket(stack, mi.pss, mi.name, true);
1622                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1623                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1624                                    stack.append("(");
1625                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1626                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1627                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1628                                            stack.append(":");
1629                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1630                                        }
1631                                    }
1632                                    stack.append(")");
1633                                }
1634                            }
1635
1636                            logBuilder.append("  ");
1637                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1638                            logBuilder.append(' ');
1639                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1640                            logBuilder.append(' ');
1641                            ProcessList.appendRamKb(logBuilder, mi.pss);
1642                            logBuilder.append(" kB: ");
1643                            logBuilder.append(mi.name);
1644                            logBuilder.append(" (");
1645                            logBuilder.append(mi.pid);
1646                            logBuilder.append(") ");
1647                            logBuilder.append(mi.adjType);
1648                            logBuilder.append('\n');
1649                            if (mi.adjReason != null) {
1650                                logBuilder.append("                      ");
1651                                logBuilder.append(mi.adjReason);
1652                                logBuilder.append('\n');
1653                            }
1654                        }
1655
1656                        logBuilder.append("           ");
1657                        ProcessList.appendRamKb(logBuilder, totalPss);
1658                        logBuilder.append(" kB: TOTAL\n");
1659
1660                        long[] infos = new long[Debug.MEMINFO_COUNT];
1661                        Debug.getMemInfo(infos);
1662                        logBuilder.append("  MemInfo: ");
1663                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1664                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1665                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1666                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1667                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1668                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1669                            logBuilder.append("  ZRAM: ");
1670                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1671                            logBuilder.append(" kB RAM, ");
1672                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1673                            logBuilder.append(" kB swap total, ");
1674                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1675                            logBuilder.append(" kB swap free\n");
1676                        }
1677                        Slog.i(TAG, logBuilder.toString());
1678
1679                        StringBuilder dropBuilder = new StringBuilder(1024);
1680                        /*
1681                        StringWriter oomSw = new StringWriter();
1682                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1683                        StringWriter catSw = new StringWriter();
1684                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1685                        String[] emptyArgs = new String[] { };
1686                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1687                        oomPw.flush();
1688                        String oomString = oomSw.toString();
1689                        */
1690                        dropBuilder.append(stack);
1691                        dropBuilder.append('\n');
1692                        dropBuilder.append('\n');
1693                        dropBuilder.append(logBuilder);
1694                        dropBuilder.append('\n');
1695                        /*
1696                        dropBuilder.append(oomString);
1697                        dropBuilder.append('\n');
1698                        */
1699                        StringWriter catSw = new StringWriter();
1700                        synchronized (ActivityManagerService.this) {
1701                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                            String[] emptyArgs = new String[] { };
1703                            catPw.println();
1704                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1705                            catPw.println();
1706                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1707                                    false, false, null);
1708                            catPw.println();
1709                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1710                            catPw.flush();
1711                        }
1712                        dropBuilder.append(catSw.toString());
1713                        addErrorToDropBox("lowmem", null, "system_server", null,
1714                                null, tag.toString(), dropBuilder.toString(), null, null);
1715                        //Slog.i(TAG, "Sent to dropbox:");
1716                        //Slog.i(TAG, dropBuilder.toString());
1717                        synchronized (ActivityManagerService.this) {
1718                            long now = SystemClock.uptimeMillis();
1719                            if (mLastMemUsageReportTime < now) {
1720                                mLastMemUsageReportTime = now;
1721                            }
1722                        }
1723                    }
1724                };
1725                thread.start();
1726                break;
1727            }
1728            case REPORT_USER_SWITCH_MSG: {
1729                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1730                break;
1731            }
1732            case CONTINUE_USER_SWITCH_MSG: {
1733                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1734                break;
1735            }
1736            case USER_SWITCH_TIMEOUT_MSG: {
1737                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1738                break;
1739            }
1740            case IMMERSIVE_MODE_LOCK_MSG: {
1741                final boolean nextState = (msg.arg1 != 0);
1742                if (mUpdateLock.isHeld() != nextState) {
1743                    if (DEBUG_IMMERSIVE) {
1744                        final ActivityRecord r = (ActivityRecord) msg.obj;
1745                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1746                    }
1747                    if (nextState) {
1748                        mUpdateLock.acquire();
1749                    } else {
1750                        mUpdateLock.release();
1751                    }
1752                }
1753                break;
1754            }
1755            case PERSIST_URI_GRANTS_MSG: {
1756                writeGrantedUriPermissions();
1757                break;
1758            }
1759            case REQUEST_ALL_PSS_MSG: {
1760                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1761                break;
1762            }
1763            case START_PROFILES_MSG: {
1764                synchronized (ActivityManagerService.this) {
1765                    startProfilesLocked();
1766                }
1767                break;
1768            }
1769            case UPDATE_TIME: {
1770                synchronized (ActivityManagerService.this) {
1771                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1772                        ProcessRecord r = mLruProcesses.get(i);
1773                        if (r.thread != null) {
1774                            try {
1775                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1776                            } catch (RemoteException ex) {
1777                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1778                            }
1779                        }
1780                    }
1781                }
1782                break;
1783            }
1784            case SYSTEM_USER_START_MSG: {
1785                mSystemServiceManager.startUser(msg.arg1);
1786                break;
1787            }
1788            case SYSTEM_USER_CURRENT_MSG: {
1789                mSystemServiceManager.switchUser(msg.arg1);
1790                break;
1791            }
1792            }
1793        }
1794    };
1795
1796    static final int COLLECT_PSS_BG_MSG = 1;
1797
1798    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1799        @Override
1800        public void handleMessage(Message msg) {
1801            switch (msg.what) {
1802            case COLLECT_PSS_BG_MSG: {
1803                int i=0, num=0;
1804                long start = SystemClock.uptimeMillis();
1805                long[] tmp = new long[1];
1806                do {
1807                    ProcessRecord proc;
1808                    int procState;
1809                    int pid;
1810                    synchronized (ActivityManagerService.this) {
1811                        if (i >= mPendingPssProcesses.size()) {
1812                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1813                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1814                            mPendingPssProcesses.clear();
1815                            return;
1816                        }
1817                        proc = mPendingPssProcesses.get(i);
1818                        procState = proc.pssProcState;
1819                        if (proc.thread != null && procState == proc.setProcState) {
1820                            pid = proc.pid;
1821                        } else {
1822                            proc = null;
1823                            pid = 0;
1824                        }
1825                        i++;
1826                    }
1827                    if (proc != null) {
1828                        long pss = Debug.getPss(pid, tmp);
1829                        synchronized (ActivityManagerService.this) {
1830                            if (proc.thread != null && proc.setProcState == procState
1831                                    && proc.pid == pid) {
1832                                num++;
1833                                proc.lastPssTime = SystemClock.uptimeMillis();
1834                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1835                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1836                                        + ": " + pss + " lastPss=" + proc.lastPss
1837                                        + " state=" + ProcessList.makeProcStateString(procState));
1838                                if (proc.initialIdlePss == 0) {
1839                                    proc.initialIdlePss = pss;
1840                                }
1841                                proc.lastPss = pss;
1842                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1843                                    proc.lastCachedPss = pss;
1844                                }
1845                            }
1846                        }
1847                    }
1848                } while (true);
1849            }
1850            }
1851        }
1852    };
1853
1854    /**
1855     * Monitor for package changes and update our internal state.
1856     */
1857    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1858        @Override
1859        public void onPackageRemoved(String packageName, int uid) {
1860            // Remove all tasks with activities in the specified package from the list of recent tasks
1861            synchronized (ActivityManagerService.this) {
1862                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1863                    TaskRecord tr = mRecentTasks.get(i);
1864                    ComponentName cn = tr.intent.getComponent();
1865                    if (cn != null && cn.getPackageName().equals(packageName)) {
1866                        // If the package name matches, remove the task and kill the process
1867                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1868                    }
1869                }
1870            }
1871        }
1872
1873        @Override
1874        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1875            onPackageModified(packageName);
1876            return true;
1877        }
1878
1879        @Override
1880        public void onPackageModified(String packageName) {
1881            final PackageManager pm = mContext.getPackageManager();
1882            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1883                    new ArrayList<Pair<Intent, Integer>>();
1884            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1885            // Copy the list of recent tasks so that we don't hold onto the lock on
1886            // ActivityManagerService for long periods while checking if components exist.
1887            synchronized (ActivityManagerService.this) {
1888                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1889                    TaskRecord tr = mRecentTasks.get(i);
1890                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1891                }
1892            }
1893            // Check the recent tasks and filter out all tasks with components that no longer exist.
1894            Intent tmpI = new Intent();
1895            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1896                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1897                ComponentName cn = p.first.getComponent();
1898                if (cn != null && cn.getPackageName().equals(packageName)) {
1899                    try {
1900                        // Add the task to the list to remove if the component no longer exists
1901                        tmpI.setComponent(cn);
1902                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1903                            tasksToRemove.add(p.second);
1904                        }
1905                    } catch (Exception e) {}
1906                }
1907            }
1908            // Prune all the tasks with removed components from the list of recent tasks
1909            synchronized (ActivityManagerService.this) {
1910                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1911                    // Remove the task but don't kill the process (since other components in that
1912                    // package may still be running and in the background)
1913                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1914                }
1915            }
1916        }
1917
1918        @Override
1919        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1920            // Force stop the specified packages
1921            if (packages != null) {
1922                for (String pkg : packages) {
1923                    synchronized (ActivityManagerService.this) {
1924                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1925                                "finished booting")) {
1926                            return true;
1927                        }
1928                    }
1929                }
1930            }
1931            return false;
1932        }
1933    };
1934
1935    public void setSystemProcess() {
1936        try {
1937            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1938            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1939            ServiceManager.addService("meminfo", new MemBinder(this));
1940            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1941            ServiceManager.addService("dbinfo", new DbBinder(this));
1942            if (MONITOR_CPU_USAGE) {
1943                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1944            }
1945            ServiceManager.addService("permission", new PermissionController(this));
1946
1947            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1948                    "android", STOCK_PM_FLAGS);
1949            mSystemThread.installSystemApplicationInfo(info);
1950
1951            synchronized (this) {
1952                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1953                app.persistent = true;
1954                app.pid = MY_PID;
1955                app.maxAdj = ProcessList.SYSTEM_ADJ;
1956                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1957                mProcessNames.put(app.processName, app.uid, app);
1958                synchronized (mPidsSelfLocked) {
1959                    mPidsSelfLocked.put(app.pid, app);
1960                }
1961                updateLruProcessLocked(app, false, null);
1962                updateOomAdjLocked();
1963            }
1964        } catch (PackageManager.NameNotFoundException e) {
1965            throw new RuntimeException(
1966                    "Unable to find android system package", e);
1967        }
1968    }
1969
1970    public void setWindowManager(WindowManagerService wm) {
1971        mWindowManager = wm;
1972        mStackSupervisor.setWindowManager(wm);
1973    }
1974
1975    public void startObservingNativeCrashes() {
1976        final NativeCrashListener ncl = new NativeCrashListener(this);
1977        ncl.start();
1978    }
1979
1980    public IAppOpsService getAppOpsService() {
1981        return mAppOpsService;
1982    }
1983
1984    static class MemBinder extends Binder {
1985        ActivityManagerService mActivityManagerService;
1986        MemBinder(ActivityManagerService activityManagerService) {
1987            mActivityManagerService = activityManagerService;
1988        }
1989
1990        @Override
1991        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1992            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1993                    != PackageManager.PERMISSION_GRANTED) {
1994                pw.println("Permission Denial: can't dump meminfo from from pid="
1995                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1996                        + " without permission " + android.Manifest.permission.DUMP);
1997                return;
1998            }
1999
2000            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2001        }
2002    }
2003
2004    static class GraphicsBinder extends Binder {
2005        ActivityManagerService mActivityManagerService;
2006        GraphicsBinder(ActivityManagerService activityManagerService) {
2007            mActivityManagerService = activityManagerService;
2008        }
2009
2010        @Override
2011        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2012            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2013                    != PackageManager.PERMISSION_GRANTED) {
2014                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2015                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2016                        + " without permission " + android.Manifest.permission.DUMP);
2017                return;
2018            }
2019
2020            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2021        }
2022    }
2023
2024    static class DbBinder extends Binder {
2025        ActivityManagerService mActivityManagerService;
2026        DbBinder(ActivityManagerService activityManagerService) {
2027            mActivityManagerService = activityManagerService;
2028        }
2029
2030        @Override
2031        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2032            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2033                    != PackageManager.PERMISSION_GRANTED) {
2034                pw.println("Permission Denial: can't dump dbinfo from from pid="
2035                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2036                        + " without permission " + android.Manifest.permission.DUMP);
2037                return;
2038            }
2039
2040            mActivityManagerService.dumpDbInfo(fd, pw, args);
2041        }
2042    }
2043
2044    static class CpuBinder extends Binder {
2045        ActivityManagerService mActivityManagerService;
2046        CpuBinder(ActivityManagerService activityManagerService) {
2047            mActivityManagerService = activityManagerService;
2048        }
2049
2050        @Override
2051        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2052            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2053                    != PackageManager.PERMISSION_GRANTED) {
2054                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2055                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2056                        + " without permission " + android.Manifest.permission.DUMP);
2057                return;
2058            }
2059
2060            synchronized (mActivityManagerService.mProcessCpuThread) {
2061                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2062                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2063                        SystemClock.uptimeMillis()));
2064            }
2065        }
2066    }
2067
2068    public static final class Lifecycle extends SystemService {
2069        private final ActivityManagerService mService;
2070
2071        public Lifecycle(Context context) {
2072            super(context);
2073            mService = new ActivityManagerService(context);
2074        }
2075
2076        @Override
2077        public void onStart() {
2078            mService.start();
2079        }
2080
2081        public ActivityManagerService getService() {
2082            return mService;
2083        }
2084    }
2085
2086    // Note: This method is invoked on the main thread but may need to attach various
2087    // handlers to other threads.  So take care to be explicit about the looper.
2088    public ActivityManagerService(Context systemContext) {
2089        mContext = systemContext;
2090        mFactoryTest = FactoryTest.getMode();
2091        mSystemThread = ActivityThread.currentActivityThread();
2092
2093        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2094
2095        mHandlerThread = new ServiceThread(TAG,
2096                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2097        mHandlerThread.start();
2098        mHandler = new MainHandler(mHandlerThread.getLooper());
2099
2100        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2101                "foreground", BROADCAST_FG_TIMEOUT, false);
2102        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2103                "background", BROADCAST_BG_TIMEOUT, true);
2104        mBroadcastQueues[0] = mFgBroadcastQueue;
2105        mBroadcastQueues[1] = mBgBroadcastQueue;
2106
2107        mServices = new ActiveServices(this);
2108        mProviderMap = new ProviderMap(this);
2109
2110        // TODO: Move creation of battery stats service outside of activity manager service.
2111        File dataDir = Environment.getDataDirectory();
2112        File systemDir = new File(dataDir, "system");
2113        systemDir.mkdirs();
2114        mBatteryStatsService = new BatteryStatsService(new File(
2115                systemDir, "batterystats.bin").toString(), mHandler);
2116        mBatteryStatsService.getActiveStatistics().readLocked();
2117        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2118        mOnBattery = DEBUG_POWER ? true
2119                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2120        mBatteryStatsService.getActiveStatistics().setCallback(this);
2121
2122        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2123
2124        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2125        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2126
2127        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2128
2129        // User 0 is the first and only user that runs at boot.
2130        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2131        mUserLru.add(Integer.valueOf(0));
2132        updateStartedUserArrayLocked();
2133
2134        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2135            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2136
2137        mConfiguration.setToDefaults();
2138        mConfiguration.setLocale(Locale.getDefault());
2139
2140        mConfigurationSeq = mConfiguration.seq = 1;
2141        mProcessCpuTracker.init();
2142
2143        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2144        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2145        mStackSupervisor = new ActivityStackSupervisor(this);
2146        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2147
2148        mProcessCpuThread = new Thread("CpuTracker") {
2149            @Override
2150            public void run() {
2151                while (true) {
2152                    try {
2153                        try {
2154                            synchronized(this) {
2155                                final long now = SystemClock.uptimeMillis();
2156                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2157                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2158                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2159                                //        + ", write delay=" + nextWriteDelay);
2160                                if (nextWriteDelay < nextCpuDelay) {
2161                                    nextCpuDelay = nextWriteDelay;
2162                                }
2163                                if (nextCpuDelay > 0) {
2164                                    mProcessCpuMutexFree.set(true);
2165                                    this.wait(nextCpuDelay);
2166                                }
2167                            }
2168                        } catch (InterruptedException e) {
2169                        }
2170                        updateCpuStatsNow();
2171                    } catch (Exception e) {
2172                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2173                    }
2174                }
2175            }
2176        };
2177
2178        Watchdog.getInstance().addMonitor(this);
2179        Watchdog.getInstance().addThread(mHandler);
2180    }
2181
2182    public void setSystemServiceManager(SystemServiceManager mgr) {
2183        mSystemServiceManager = mgr;
2184    }
2185
2186    private void start() {
2187        mProcessCpuThread.start();
2188
2189        mBatteryStatsService.publish(mContext);
2190        mUsageStatsService.publish(mContext);
2191        mAppOpsService.publish(mContext);
2192
2193        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2194    }
2195
2196    @Override
2197    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2198            throws RemoteException {
2199        if (code == SYSPROPS_TRANSACTION) {
2200            // We need to tell all apps about the system property change.
2201            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2202            synchronized(this) {
2203                final int NP = mProcessNames.getMap().size();
2204                for (int ip=0; ip<NP; ip++) {
2205                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2206                    final int NA = apps.size();
2207                    for (int ia=0; ia<NA; ia++) {
2208                        ProcessRecord app = apps.valueAt(ia);
2209                        if (app.thread != null) {
2210                            procs.add(app.thread.asBinder());
2211                        }
2212                    }
2213                }
2214            }
2215
2216            int N = procs.size();
2217            for (int i=0; i<N; i++) {
2218                Parcel data2 = Parcel.obtain();
2219                try {
2220                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2221                } catch (RemoteException e) {
2222                }
2223                data2.recycle();
2224            }
2225        }
2226        try {
2227            return super.onTransact(code, data, reply, flags);
2228        } catch (RuntimeException e) {
2229            // The activity manager only throws security exceptions, so let's
2230            // log all others.
2231            if (!(e instanceof SecurityException)) {
2232                Slog.wtf(TAG, "Activity Manager Crash", e);
2233            }
2234            throw e;
2235        }
2236    }
2237
2238    void updateCpuStats() {
2239        final long now = SystemClock.uptimeMillis();
2240        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2241            return;
2242        }
2243        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2244            synchronized (mProcessCpuThread) {
2245                mProcessCpuThread.notify();
2246            }
2247        }
2248    }
2249
2250    void updateCpuStatsNow() {
2251        synchronized (mProcessCpuThread) {
2252            mProcessCpuMutexFree.set(false);
2253            final long now = SystemClock.uptimeMillis();
2254            boolean haveNewCpuStats = false;
2255
2256            if (MONITOR_CPU_USAGE &&
2257                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2258                mLastCpuTime.set(now);
2259                haveNewCpuStats = true;
2260                mProcessCpuTracker.update();
2261                //Slog.i(TAG, mProcessCpu.printCurrentState());
2262                //Slog.i(TAG, "Total CPU usage: "
2263                //        + mProcessCpu.getTotalCpuPercent() + "%");
2264
2265                // Slog the cpu usage if the property is set.
2266                if ("true".equals(SystemProperties.get("events.cpu"))) {
2267                    int user = mProcessCpuTracker.getLastUserTime();
2268                    int system = mProcessCpuTracker.getLastSystemTime();
2269                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2270                    int irq = mProcessCpuTracker.getLastIrqTime();
2271                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2272                    int idle = mProcessCpuTracker.getLastIdleTime();
2273
2274                    int total = user + system + iowait + irq + softIrq + idle;
2275                    if (total == 0) total = 1;
2276
2277                    EventLog.writeEvent(EventLogTags.CPU,
2278                            ((user+system+iowait+irq+softIrq) * 100) / total,
2279                            (user * 100) / total,
2280                            (system * 100) / total,
2281                            (iowait * 100) / total,
2282                            (irq * 100) / total,
2283                            (softIrq * 100) / total);
2284                }
2285            }
2286
2287            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2288            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2289            synchronized(bstats) {
2290                synchronized(mPidsSelfLocked) {
2291                    if (haveNewCpuStats) {
2292                        if (mOnBattery) {
2293                            int perc = bstats.startAddingCpuLocked();
2294                            int totalUTime = 0;
2295                            int totalSTime = 0;
2296                            final int N = mProcessCpuTracker.countStats();
2297                            for (int i=0; i<N; i++) {
2298                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2299                                if (!st.working) {
2300                                    continue;
2301                                }
2302                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2303                                int otherUTime = (st.rel_utime*perc)/100;
2304                                int otherSTime = (st.rel_stime*perc)/100;
2305                                totalUTime += otherUTime;
2306                                totalSTime += otherSTime;
2307                                if (pr != null) {
2308                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2309                                    if (ps == null || !ps.isActive()) {
2310                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2311                                                pr.info.uid, pr.processName);
2312                                    }
2313                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2314                                            st.rel_stime-otherSTime);
2315                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2316                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2317                                } else {
2318                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2319                                    if (ps == null || !ps.isActive()) {
2320                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2321                                                bstats.mapUid(st.uid), st.name);
2322                                    }
2323                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2324                                            st.rel_stime-otherSTime);
2325                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2326                                }
2327                            }
2328                            bstats.finishAddingCpuLocked(perc, totalUTime,
2329                                    totalSTime, cpuSpeedTimes);
2330                        }
2331                    }
2332                }
2333
2334                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2335                    mLastWriteTime = now;
2336                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2337                }
2338            }
2339        }
2340    }
2341
2342    @Override
2343    public void batteryNeedsCpuUpdate() {
2344        updateCpuStatsNow();
2345    }
2346
2347    @Override
2348    public void batteryPowerChanged(boolean onBattery) {
2349        // When plugging in, update the CPU stats first before changing
2350        // the plug state.
2351        updateCpuStatsNow();
2352        synchronized (this) {
2353            synchronized(mPidsSelfLocked) {
2354                mOnBattery = DEBUG_POWER ? true : onBattery;
2355            }
2356        }
2357    }
2358
2359    /**
2360     * Initialize the application bind args. These are passed to each
2361     * process when the bindApplication() IPC is sent to the process. They're
2362     * lazily setup to make sure the services are running when they're asked for.
2363     */
2364    private HashMap<String, IBinder> getCommonServicesLocked() {
2365        if (mAppBindArgs == null) {
2366            mAppBindArgs = new HashMap<String, IBinder>();
2367
2368            // Setup the application init args
2369            mAppBindArgs.put("package", ServiceManager.getService("package"));
2370            mAppBindArgs.put("window", ServiceManager.getService("window"));
2371            mAppBindArgs.put(Context.ALARM_SERVICE,
2372                    ServiceManager.getService(Context.ALARM_SERVICE));
2373        }
2374        return mAppBindArgs;
2375    }
2376
2377    final void setFocusedActivityLocked(ActivityRecord r) {
2378        if (mFocusedActivity != r) {
2379            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2380            mFocusedActivity = r;
2381            if (r.task != null && r.task.voiceInteractor != null) {
2382                startRunningVoiceLocked();
2383            } else {
2384                finishRunningVoiceLocked();
2385            }
2386            mStackSupervisor.setFocusedStack(r);
2387            if (r != null) {
2388                mWindowManager.setFocusedApp(r.appToken, true);
2389            }
2390            applyUpdateLockStateLocked(r);
2391        }
2392    }
2393
2394    final void clearFocusedActivity(ActivityRecord r) {
2395        if (mFocusedActivity == r) {
2396            mFocusedActivity = null;
2397        }
2398    }
2399
2400    @Override
2401    public void setFocusedStack(int stackId) {
2402        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2403        synchronized (ActivityManagerService.this) {
2404            ActivityStack stack = mStackSupervisor.getStack(stackId);
2405            if (stack != null) {
2406                ActivityRecord r = stack.topRunningActivityLocked(null);
2407                if (r != null) {
2408                    setFocusedActivityLocked(r);
2409                }
2410            }
2411        }
2412    }
2413
2414    @Override
2415    public void notifyActivityDrawn(IBinder token) {
2416        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2417        synchronized (this) {
2418            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2419            if (r != null) {
2420                r.task.stack.notifyActivityDrawnLocked(r);
2421            }
2422        }
2423    }
2424
2425    final void applyUpdateLockStateLocked(ActivityRecord r) {
2426        // Modifications to the UpdateLock state are done on our handler, outside
2427        // the activity manager's locks.  The new state is determined based on the
2428        // state *now* of the relevant activity record.  The object is passed to
2429        // the handler solely for logging detail, not to be consulted/modified.
2430        final boolean nextState = r != null && r.immersive;
2431        mHandler.sendMessage(
2432                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2433    }
2434
2435    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2436        Message msg = Message.obtain();
2437        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2438        msg.obj = r.task.askedCompatMode ? null : r;
2439        mHandler.sendMessage(msg);
2440    }
2441
2442    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2443            String what, Object obj, ProcessRecord srcApp) {
2444        app.lastActivityTime = now;
2445
2446        if (app.activities.size() > 0) {
2447            // Don't want to touch dependent processes that are hosting activities.
2448            return index;
2449        }
2450
2451        int lrui = mLruProcesses.lastIndexOf(app);
2452        if (lrui < 0) {
2453            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2454                    + what + " " + obj + " from " + srcApp);
2455            return index;
2456        }
2457
2458        if (lrui >= index) {
2459            // Don't want to cause this to move dependent processes *back* in the
2460            // list as if they were less frequently used.
2461            return index;
2462        }
2463
2464        if (lrui >= mLruProcessActivityStart) {
2465            // Don't want to touch dependent processes that are hosting activities.
2466            return index;
2467        }
2468
2469        mLruProcesses.remove(lrui);
2470        if (index > 0) {
2471            index--;
2472        }
2473        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2474                + " in LRU list: " + app);
2475        mLruProcesses.add(index, app);
2476        return index;
2477    }
2478
2479    final void removeLruProcessLocked(ProcessRecord app) {
2480        int lrui = mLruProcesses.lastIndexOf(app);
2481        if (lrui >= 0) {
2482            if (lrui <= mLruProcessActivityStart) {
2483                mLruProcessActivityStart--;
2484            }
2485            if (lrui <= mLruProcessServiceStart) {
2486                mLruProcessServiceStart--;
2487            }
2488            mLruProcesses.remove(lrui);
2489        }
2490    }
2491
2492    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2493            ProcessRecord client) {
2494        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2495                || app.treatLikeActivity;
2496        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2497        if (!activityChange && hasActivity) {
2498            // The process has activities, so we are only allowing activity-based adjustments
2499            // to move it.  It should be kept in the front of the list with other
2500            // processes that have activities, and we don't want those to change their
2501            // order except due to activity operations.
2502            return;
2503        }
2504
2505        mLruSeq++;
2506        final long now = SystemClock.uptimeMillis();
2507        app.lastActivityTime = now;
2508
2509        // First a quick reject: if the app is already at the position we will
2510        // put it, then there is nothing to do.
2511        if (hasActivity) {
2512            final int N = mLruProcesses.size();
2513            if (N > 0 && mLruProcesses.get(N-1) == app) {
2514                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2515                return;
2516            }
2517        } else {
2518            if (mLruProcessServiceStart > 0
2519                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2520                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2521                return;
2522            }
2523        }
2524
2525        int lrui = mLruProcesses.lastIndexOf(app);
2526
2527        if (app.persistent && lrui >= 0) {
2528            // We don't care about the position of persistent processes, as long as
2529            // they are in the list.
2530            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2531            return;
2532        }
2533
2534        /* In progress: compute new position first, so we can avoid doing work
2535           if the process is not actually going to move.  Not yet working.
2536        int addIndex;
2537        int nextIndex;
2538        boolean inActivity = false, inService = false;
2539        if (hasActivity) {
2540            // Process has activities, put it at the very tipsy-top.
2541            addIndex = mLruProcesses.size();
2542            nextIndex = mLruProcessServiceStart;
2543            inActivity = true;
2544        } else if (hasService) {
2545            // Process has services, put it at the top of the service list.
2546            addIndex = mLruProcessActivityStart;
2547            nextIndex = mLruProcessServiceStart;
2548            inActivity = true;
2549            inService = true;
2550        } else  {
2551            // Process not otherwise of interest, it goes to the top of the non-service area.
2552            addIndex = mLruProcessServiceStart;
2553            if (client != null) {
2554                int clientIndex = mLruProcesses.lastIndexOf(client);
2555                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2556                        + app);
2557                if (clientIndex >= 0 && addIndex > clientIndex) {
2558                    addIndex = clientIndex;
2559                }
2560            }
2561            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2562        }
2563
2564        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2565                + mLruProcessActivityStart + "): " + app);
2566        */
2567
2568        if (lrui >= 0) {
2569            if (lrui < mLruProcessActivityStart) {
2570                mLruProcessActivityStart--;
2571            }
2572            if (lrui < mLruProcessServiceStart) {
2573                mLruProcessServiceStart--;
2574            }
2575            /*
2576            if (addIndex > lrui) {
2577                addIndex--;
2578            }
2579            if (nextIndex > lrui) {
2580                nextIndex--;
2581            }
2582            */
2583            mLruProcesses.remove(lrui);
2584        }
2585
2586        /*
2587        mLruProcesses.add(addIndex, app);
2588        if (inActivity) {
2589            mLruProcessActivityStart++;
2590        }
2591        if (inService) {
2592            mLruProcessActivityStart++;
2593        }
2594        */
2595
2596        int nextIndex;
2597        if (hasActivity) {
2598            final int N = mLruProcesses.size();
2599            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2600                // Process doesn't have activities, but has clients with
2601                // activities...  move it up, but one below the top (the top
2602                // should always have a real activity).
2603                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2604                mLruProcesses.add(N-1, app);
2605                // To keep it from spamming the LRU list (by making a bunch of clients),
2606                // we will push down any other entries owned by the app.
2607                final int uid = app.info.uid;
2608                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2609                    ProcessRecord subProc = mLruProcesses.get(i);
2610                    if (subProc.info.uid == uid) {
2611                        // We want to push this one down the list.  If the process after
2612                        // it is for the same uid, however, don't do so, because we don't
2613                        // want them internally to be re-ordered.
2614                        if (mLruProcesses.get(i-1).info.uid != uid) {
2615                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2616                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2617                            ProcessRecord tmp = mLruProcesses.get(i);
2618                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2619                            mLruProcesses.set(i-1, tmp);
2620                            i--;
2621                        }
2622                    } else {
2623                        // A gap, we can stop here.
2624                        break;
2625                    }
2626                }
2627            } else {
2628                // Process has activities, put it at the very tipsy-top.
2629                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2630                mLruProcesses.add(app);
2631            }
2632            nextIndex = mLruProcessServiceStart;
2633        } else if (hasService) {
2634            // Process has services, put it at the top of the service list.
2635            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2636            mLruProcesses.add(mLruProcessActivityStart, app);
2637            nextIndex = mLruProcessServiceStart;
2638            mLruProcessActivityStart++;
2639        } else  {
2640            // Process not otherwise of interest, it goes to the top of the non-service area.
2641            int index = mLruProcessServiceStart;
2642            if (client != null) {
2643                // If there is a client, don't allow the process to be moved up higher
2644                // in the list than that client.
2645                int clientIndex = mLruProcesses.lastIndexOf(client);
2646                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2647                        + " when updating " + app);
2648                if (clientIndex <= lrui) {
2649                    // Don't allow the client index restriction to push it down farther in the
2650                    // list than it already is.
2651                    clientIndex = lrui;
2652                }
2653                if (clientIndex >= 0 && index > clientIndex) {
2654                    index = clientIndex;
2655                }
2656            }
2657            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2658            mLruProcesses.add(index, app);
2659            nextIndex = index-1;
2660            mLruProcessActivityStart++;
2661            mLruProcessServiceStart++;
2662        }
2663
2664        // If the app is currently using a content provider or service,
2665        // bump those processes as well.
2666        for (int j=app.connections.size()-1; j>=0; j--) {
2667            ConnectionRecord cr = app.connections.valueAt(j);
2668            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2669                    && cr.binding.service.app != null
2670                    && cr.binding.service.app.lruSeq != mLruSeq
2671                    && !cr.binding.service.app.persistent) {
2672                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2673                        "service connection", cr, app);
2674            }
2675        }
2676        for (int j=app.conProviders.size()-1; j>=0; j--) {
2677            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2678            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2679                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2680                        "provider reference", cpr, app);
2681            }
2682        }
2683    }
2684
2685    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2686        if (uid == Process.SYSTEM_UID) {
2687            // The system gets to run in any process.  If there are multiple
2688            // processes with the same uid, just pick the first (this
2689            // should never happen).
2690            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2691            if (procs == null) return null;
2692            final int N = procs.size();
2693            for (int i = 0; i < N; i++) {
2694                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2695            }
2696        }
2697        ProcessRecord proc = mProcessNames.get(processName, uid);
2698        if (false && proc != null && !keepIfLarge
2699                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2700                && proc.lastCachedPss >= 4000) {
2701            // Turn this condition on to cause killing to happen regularly, for testing.
2702            if (proc.baseProcessTracker != null) {
2703                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2704            }
2705            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2706                    + "k from cached");
2707        } else if (proc != null && !keepIfLarge
2708                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2709                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2710            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2711            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2712                if (proc.baseProcessTracker != null) {
2713                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2714                }
2715                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2716                        + "k from cached");
2717            }
2718        }
2719        return proc;
2720    }
2721
2722    void ensurePackageDexOpt(String packageName) {
2723        IPackageManager pm = AppGlobals.getPackageManager();
2724        try {
2725            if (pm.performDexOpt(packageName)) {
2726                mDidDexOpt = true;
2727            }
2728        } catch (RemoteException e) {
2729        }
2730    }
2731
2732    boolean isNextTransitionForward() {
2733        int transit = mWindowManager.getPendingAppTransition();
2734        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2735                || transit == AppTransition.TRANSIT_TASK_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2737    }
2738
2739    final ProcessRecord startProcessLocked(String processName,
2740            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2741            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2742            boolean isolated, boolean keepIfLarge) {
2743        ProcessRecord app;
2744        if (!isolated) {
2745            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2746        } else {
2747            // If this is an isolated process, it can't re-use an existing process.
2748            app = null;
2749        }
2750        // We don't have to do anything more if:
2751        // (1) There is an existing application record; and
2752        // (2) The caller doesn't think it is dead, OR there is no thread
2753        //     object attached to it so we know it couldn't have crashed; and
2754        // (3) There is a pid assigned to it, so it is either starting or
2755        //     already running.
2756        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2757                + " app=" + app + " knownToBeDead=" + knownToBeDead
2758                + " thread=" + (app != null ? app.thread : null)
2759                + " pid=" + (app != null ? app.pid : -1));
2760        if (app != null && app.pid > 0) {
2761            if (!knownToBeDead || app.thread == null) {
2762                // We already have the app running, or are waiting for it to
2763                // come up (we have a pid but not yet its thread), so keep it.
2764                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2765                // If this is a new package in the process, add the package to the list
2766                app.addPackage(info.packageName, mProcessStats);
2767                return app;
2768            }
2769
2770            // An application record is attached to a previous process,
2771            // clean it up now.
2772            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2773            handleAppDiedLocked(app, true, true);
2774        }
2775
2776        String hostingNameStr = hostingName != null
2777                ? hostingName.flattenToShortString() : null;
2778
2779        if (!isolated) {
2780            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2781                // If we are in the background, then check to see if this process
2782                // is bad.  If so, we will just silently fail.
2783                if (mBadProcesses.get(info.processName, info.uid) != null) {
2784                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2785                            + "/" + info.processName);
2786                    return null;
2787                }
2788            } else {
2789                // When the user is explicitly starting a process, then clear its
2790                // crash count so that we won't make it bad until they see at
2791                // least one crash dialog again, and make the process good again
2792                // if it had been bad.
2793                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2794                        + "/" + info.processName);
2795                mProcessCrashTimes.remove(info.processName, info.uid);
2796                if (mBadProcesses.get(info.processName, info.uid) != null) {
2797                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2798                            UserHandle.getUserId(info.uid), info.uid,
2799                            info.processName);
2800                    mBadProcesses.remove(info.processName, info.uid);
2801                    if (app != null) {
2802                        app.bad = false;
2803                    }
2804                }
2805            }
2806        }
2807
2808        if (app == null) {
2809            app = newProcessRecordLocked(info, processName, isolated);
2810            if (app == null) {
2811                Slog.w(TAG, "Failed making new process record for "
2812                        + processName + "/" + info.uid + " isolated=" + isolated);
2813                return null;
2814            }
2815            mProcessNames.put(processName, app.uid, app);
2816            if (isolated) {
2817                mIsolatedProcesses.put(app.uid, app);
2818            }
2819        } else {
2820            // If this is a new package in the process, add the package to the list
2821            app.addPackage(info.packageName, mProcessStats);
2822        }
2823
2824        // If the system is not ready yet, then hold off on starting this
2825        // process until it is.
2826        if (!mProcessesReady
2827                && !isAllowedWhileBooting(info)
2828                && !allowWhileBooting) {
2829            if (!mProcessesOnHold.contains(app)) {
2830                mProcessesOnHold.add(app);
2831            }
2832            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2833            return app;
2834        }
2835
2836        startProcessLocked(app, hostingType, hostingNameStr);
2837        return (app.pid != 0) ? app : null;
2838    }
2839
2840    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2841        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2842    }
2843
2844    private final void startProcessLocked(ProcessRecord app,
2845            String hostingType, String hostingNameStr) {
2846        if (app.pid > 0 && app.pid != MY_PID) {
2847            synchronized (mPidsSelfLocked) {
2848                mPidsSelfLocked.remove(app.pid);
2849                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2850            }
2851            app.setPid(0);
2852        }
2853
2854        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2855                "startProcessLocked removing on hold: " + app);
2856        mProcessesOnHold.remove(app);
2857
2858        updateCpuStats();
2859
2860        try {
2861            int uid = app.uid;
2862
2863            int[] gids = null;
2864            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2865            if (!app.isolated) {
2866                int[] permGids = null;
2867                try {
2868                    final PackageManager pm = mContext.getPackageManager();
2869                    permGids = pm.getPackageGids(app.info.packageName);
2870
2871                    if (Environment.isExternalStorageEmulated()) {
2872                        if (pm.checkPermission(
2873                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2874                                app.info.packageName) == PERMISSION_GRANTED) {
2875                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2876                        } else {
2877                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2878                        }
2879                    }
2880                } catch (PackageManager.NameNotFoundException e) {
2881                    Slog.w(TAG, "Unable to retrieve gids", e);
2882                }
2883
2884                /*
2885                 * Add shared application GID so applications can share some
2886                 * resources like shared libraries
2887                 */
2888                if (permGids == null) {
2889                    gids = new int[1];
2890                } else {
2891                    gids = new int[permGids.length + 1];
2892                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2893                }
2894                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2895            }
2896            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2897                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2898                        && mTopComponent != null
2899                        && app.processName.equals(mTopComponent.getPackageName())) {
2900                    uid = 0;
2901                }
2902                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2903                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2904                    uid = 0;
2905                }
2906            }
2907            int debugFlags = 0;
2908            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2909                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2910                // Also turn on CheckJNI for debuggable apps. It's quite
2911                // awkward to turn on otherwise.
2912                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2913            }
2914            // Run the app in safe mode if its manifest requests so or the
2915            // system is booted in safe mode.
2916            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2917                mSafeMode == true) {
2918                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2919            }
2920            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2921                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2922            }
2923            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2924                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2925            }
2926            if ("1".equals(SystemProperties.get("debug.assert"))) {
2927                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2928            }
2929
2930            String requiredAbi = app.info.cpuAbi;
2931            if (requiredAbi == null) {
2932                requiredAbi = Build.SUPPORTED_ABIS[0];
2933            }
2934
2935            // Start the process.  It will either succeed and return a result containing
2936            // the PID of the new process, or else throw a RuntimeException.
2937            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2938                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2939                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2940
2941            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2942            synchronized (bs) {
2943                if (bs.isOnBattery()) {
2944                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2945                }
2946            }
2947
2948            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2949                    UserHandle.getUserId(uid), startResult.pid, uid,
2950                    app.processName, hostingType,
2951                    hostingNameStr != null ? hostingNameStr : "");
2952
2953            if (app.persistent) {
2954                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2955            }
2956
2957            StringBuilder buf = mStringBuilder;
2958            buf.setLength(0);
2959            buf.append("Start proc ");
2960            buf.append(app.processName);
2961            buf.append(" for ");
2962            buf.append(hostingType);
2963            if (hostingNameStr != null) {
2964                buf.append(" ");
2965                buf.append(hostingNameStr);
2966            }
2967            buf.append(": pid=");
2968            buf.append(startResult.pid);
2969            buf.append(" uid=");
2970            buf.append(uid);
2971            buf.append(" gids={");
2972            if (gids != null) {
2973                for (int gi=0; gi<gids.length; gi++) {
2974                    if (gi != 0) buf.append(", ");
2975                    buf.append(gids[gi]);
2976
2977                }
2978            }
2979            buf.append("}");
2980            Slog.i(TAG, buf.toString());
2981            app.setPid(startResult.pid);
2982            app.usingWrapper = startResult.usingWrapper;
2983            app.removed = false;
2984            synchronized (mPidsSelfLocked) {
2985                this.mPidsSelfLocked.put(startResult.pid, app);
2986                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2987                msg.obj = app;
2988                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2989                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2990            }
2991            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2992                    app.processName, app.info.uid);
2993            if (app.isolated) {
2994                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2995            }
2996        } catch (RuntimeException e) {
2997            // XXX do better error recovery.
2998            app.setPid(0);
2999            Slog.e(TAG, "Failure starting process " + app.processName, e);
3000        }
3001    }
3002
3003    void updateUsageStats(ActivityRecord component, boolean resumed) {
3004        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3005        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3006        if (resumed) {
3007            mUsageStatsService.noteResumeComponent(component.realActivity);
3008            synchronized (stats) {
3009                stats.noteActivityResumedLocked(component.app.uid);
3010            }
3011        } else {
3012            mUsageStatsService.notePauseComponent(component.realActivity);
3013            synchronized (stats) {
3014                stats.noteActivityPausedLocked(component.app.uid);
3015            }
3016        }
3017    }
3018
3019    Intent getHomeIntent() {
3020        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3021        intent.setComponent(mTopComponent);
3022        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3023            intent.addCategory(Intent.CATEGORY_HOME);
3024        }
3025        return intent;
3026    }
3027
3028    boolean startHomeActivityLocked(int userId) {
3029        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3030                && mTopAction == null) {
3031            // We are running in factory test mode, but unable to find
3032            // the factory test app, so just sit around displaying the
3033            // error message and don't try to start anything.
3034            return false;
3035        }
3036        Intent intent = getHomeIntent();
3037        ActivityInfo aInfo =
3038            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3039        if (aInfo != null) {
3040            intent.setComponent(new ComponentName(
3041                    aInfo.applicationInfo.packageName, aInfo.name));
3042            // Don't do this if the home app is currently being
3043            // instrumented.
3044            aInfo = new ActivityInfo(aInfo);
3045            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3046            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3047                    aInfo.applicationInfo.uid, true);
3048            if (app == null || app.instrumentationClass == null) {
3049                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3050                mStackSupervisor.startHomeActivity(intent, aInfo);
3051            }
3052        }
3053
3054        return true;
3055    }
3056
3057    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3058        ActivityInfo ai = null;
3059        ComponentName comp = intent.getComponent();
3060        try {
3061            if (comp != null) {
3062                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3063            } else {
3064                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3065                        intent,
3066                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3067                            flags, userId);
3068
3069                if (info != null) {
3070                    ai = info.activityInfo;
3071                }
3072            }
3073        } catch (RemoteException e) {
3074            // ignore
3075        }
3076
3077        return ai;
3078    }
3079
3080    /**
3081     * Starts the "new version setup screen" if appropriate.
3082     */
3083    void startSetupActivityLocked() {
3084        // Only do this once per boot.
3085        if (mCheckedForSetup) {
3086            return;
3087        }
3088
3089        // We will show this screen if the current one is a different
3090        // version than the last one shown, and we are not running in
3091        // low-level factory test mode.
3092        final ContentResolver resolver = mContext.getContentResolver();
3093        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3094                Settings.Global.getInt(resolver,
3095                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3096            mCheckedForSetup = true;
3097
3098            // See if we should be showing the platform update setup UI.
3099            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3100            List<ResolveInfo> ris = mContext.getPackageManager()
3101                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3102
3103            // We don't allow third party apps to replace this.
3104            ResolveInfo ri = null;
3105            for (int i=0; ris != null && i<ris.size(); i++) {
3106                if ((ris.get(i).activityInfo.applicationInfo.flags
3107                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3108                    ri = ris.get(i);
3109                    break;
3110                }
3111            }
3112
3113            if (ri != null) {
3114                String vers = ri.activityInfo.metaData != null
3115                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3116                        : null;
3117                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3118                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3119                            Intent.METADATA_SETUP_VERSION);
3120                }
3121                String lastVers = Settings.Secure.getString(
3122                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3123                if (vers != null && !vers.equals(lastVers)) {
3124                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3125                    intent.setComponent(new ComponentName(
3126                            ri.activityInfo.packageName, ri.activityInfo.name));
3127                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3128                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3129                }
3130            }
3131        }
3132    }
3133
3134    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3135        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3136    }
3137
3138    void enforceNotIsolatedCaller(String caller) {
3139        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3140            throw new SecurityException("Isolated process not allowed to call " + caller);
3141        }
3142    }
3143
3144    @Override
3145    public int getFrontActivityScreenCompatMode() {
3146        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3147        synchronized (this) {
3148            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3149        }
3150    }
3151
3152    @Override
3153    public void setFrontActivityScreenCompatMode(int mode) {
3154        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3155                "setFrontActivityScreenCompatMode");
3156        synchronized (this) {
3157            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3158        }
3159    }
3160
3161    @Override
3162    public int getPackageScreenCompatMode(String packageName) {
3163        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3164        synchronized (this) {
3165            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3166        }
3167    }
3168
3169    @Override
3170    public void setPackageScreenCompatMode(String packageName, int mode) {
3171        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3172                "setPackageScreenCompatMode");
3173        synchronized (this) {
3174            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3175        }
3176    }
3177
3178    @Override
3179    public boolean getPackageAskScreenCompat(String packageName) {
3180        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3181        synchronized (this) {
3182            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3183        }
3184    }
3185
3186    @Override
3187    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3188        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3189                "setPackageAskScreenCompat");
3190        synchronized (this) {
3191            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3192        }
3193    }
3194
3195    private void dispatchProcessesChanged() {
3196        int N;
3197        synchronized (this) {
3198            N = mPendingProcessChanges.size();
3199            if (mActiveProcessChanges.length < N) {
3200                mActiveProcessChanges = new ProcessChangeItem[N];
3201            }
3202            mPendingProcessChanges.toArray(mActiveProcessChanges);
3203            mAvailProcessChanges.addAll(mPendingProcessChanges);
3204            mPendingProcessChanges.clear();
3205            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3206        }
3207
3208        int i = mProcessObservers.beginBroadcast();
3209        while (i > 0) {
3210            i--;
3211            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3212            if (observer != null) {
3213                try {
3214                    for (int j=0; j<N; j++) {
3215                        ProcessChangeItem item = mActiveProcessChanges[j];
3216                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3217                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3218                                    + item.pid + " uid=" + item.uid + ": "
3219                                    + item.foregroundActivities);
3220                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3221                                    item.foregroundActivities);
3222                        }
3223                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3224                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3225                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3226                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3227                        }
3228                    }
3229                } catch (RemoteException e) {
3230                }
3231            }
3232        }
3233        mProcessObservers.finishBroadcast();
3234    }
3235
3236    private void dispatchProcessDied(int pid, int uid) {
3237        int i = mProcessObservers.beginBroadcast();
3238        while (i > 0) {
3239            i--;
3240            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3241            if (observer != null) {
3242                try {
3243                    observer.onProcessDied(pid, uid);
3244                } catch (RemoteException e) {
3245                }
3246            }
3247        }
3248        mProcessObservers.finishBroadcast();
3249    }
3250
3251    final void doPendingActivityLaunchesLocked(boolean doResume) {
3252        final int N = mPendingActivityLaunches.size();
3253        if (N <= 0) {
3254            return;
3255        }
3256        for (int i=0; i<N; i++) {
3257            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3258            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3259                    doResume && i == (N-1), null);
3260        }
3261        mPendingActivityLaunches.clear();
3262    }
3263
3264    @Override
3265    public final int startActivity(IApplicationThread caller, String callingPackage,
3266            Intent intent, String resolvedType, IBinder resultTo,
3267            String resultWho, int requestCode, int startFlags,
3268            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3269        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3270                resultWho, requestCode,
3271                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3272    }
3273
3274    @Override
3275    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3276            Intent intent, String resolvedType, IBinder resultTo,
3277            String resultWho, int requestCode, int startFlags,
3278            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3279        enforceNotIsolatedCaller("startActivity");
3280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3281                false, true, "startActivity", null);
3282        // TODO: Switch to user app stacks here.
3283        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3284                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3285                null, null, options, userId, null);
3286    }
3287
3288    @Override
3289    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3290            Intent intent, String resolvedType, IBinder resultTo,
3291            String resultWho, int requestCode, int startFlags, String profileFile,
3292            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3293        enforceNotIsolatedCaller("startActivityAndWait");
3294        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3295                false, true, "startActivityAndWait", null);
3296        WaitResult res = new WaitResult();
3297        // TODO: Switch to user app stacks here.
3298        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3299                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3300                res, null, options, UserHandle.getCallingUserId(), null);
3301        return res;
3302    }
3303
3304    @Override
3305    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3306            Intent intent, String resolvedType, IBinder resultTo,
3307            String resultWho, int requestCode, int startFlags, Configuration config,
3308            Bundle options, int userId) {
3309        enforceNotIsolatedCaller("startActivityWithConfig");
3310        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3311                false, true, "startActivityWithConfig", null);
3312        // TODO: Switch to user app stacks here.
3313        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3314                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3315                null, null, null, config, options, userId, null);
3316        return ret;
3317    }
3318
3319    @Override
3320    public int startActivityIntentSender(IApplicationThread caller,
3321            IntentSender intent, Intent fillInIntent, String resolvedType,
3322            IBinder resultTo, String resultWho, int requestCode,
3323            int flagsMask, int flagsValues, Bundle options) {
3324        enforceNotIsolatedCaller("startActivityIntentSender");
3325        // Refuse possible leaked file descriptors
3326        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3327            throw new IllegalArgumentException("File descriptors passed in Intent");
3328        }
3329
3330        IIntentSender sender = intent.getTarget();
3331        if (!(sender instanceof PendingIntentRecord)) {
3332            throw new IllegalArgumentException("Bad PendingIntent object");
3333        }
3334
3335        PendingIntentRecord pir = (PendingIntentRecord)sender;
3336
3337        synchronized (this) {
3338            // If this is coming from the currently resumed activity, it is
3339            // effectively saying that app switches are allowed at this point.
3340            final ActivityStack stack = getFocusedStack();
3341            if (stack.mResumedActivity != null &&
3342                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3343                mAppSwitchesAllowedTime = 0;
3344            }
3345        }
3346        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3347                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3348        return ret;
3349    }
3350
3351    @Override
3352    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3353            Intent intent, String resolvedType, IVoiceInteractionSession session,
3354            IVoiceInteractor interactor, int startFlags, String profileFile,
3355            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3356        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3357                != PackageManager.PERMISSION_GRANTED) {
3358            String msg = "Permission Denial: startVoiceActivity() from pid="
3359                    + Binder.getCallingPid()
3360                    + ", uid=" + Binder.getCallingUid()
3361                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3362            Slog.w(TAG, msg);
3363            throw new SecurityException(msg);
3364        }
3365        if (session == null || interactor == null) {
3366            throw new NullPointerException("null session or interactor");
3367        }
3368        userId = handleIncomingUser(callingPid, callingUid, userId,
3369                false, true, "startVoiceActivity", null);
3370        // TODO: Switch to user app stacks here.
3371        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3372                resolvedType, session, interactor, null, null, 0, startFlags,
3373                profileFile, profileFd, null, null, options, userId, null);
3374    }
3375
3376    @Override
3377    public boolean startNextMatchingActivity(IBinder callingActivity,
3378            Intent intent, Bundle options) {
3379        // Refuse possible leaked file descriptors
3380        if (intent != null && intent.hasFileDescriptors() == true) {
3381            throw new IllegalArgumentException("File descriptors passed in Intent");
3382        }
3383
3384        synchronized (this) {
3385            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3386            if (r == null) {
3387                ActivityOptions.abort(options);
3388                return false;
3389            }
3390            if (r.app == null || r.app.thread == null) {
3391                // The caller is not running...  d'oh!
3392                ActivityOptions.abort(options);
3393                return false;
3394            }
3395            intent = new Intent(intent);
3396            // The caller is not allowed to change the data.
3397            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3398            // And we are resetting to find the next component...
3399            intent.setComponent(null);
3400
3401            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3402
3403            ActivityInfo aInfo = null;
3404            try {
3405                List<ResolveInfo> resolves =
3406                    AppGlobals.getPackageManager().queryIntentActivities(
3407                            intent, r.resolvedType,
3408                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3409                            UserHandle.getCallingUserId());
3410
3411                // Look for the original activity in the list...
3412                final int N = resolves != null ? resolves.size() : 0;
3413                for (int i=0; i<N; i++) {
3414                    ResolveInfo rInfo = resolves.get(i);
3415                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3416                            && rInfo.activityInfo.name.equals(r.info.name)) {
3417                        // We found the current one...  the next matching is
3418                        // after it.
3419                        i++;
3420                        if (i<N) {
3421                            aInfo = resolves.get(i).activityInfo;
3422                        }
3423                        if (debug) {
3424                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3425                                    + "/" + r.info.name);
3426                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3427                                    + "/" + aInfo.name);
3428                        }
3429                        break;
3430                    }
3431                }
3432            } catch (RemoteException e) {
3433            }
3434
3435            if (aInfo == null) {
3436                // Nobody who is next!
3437                ActivityOptions.abort(options);
3438                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3439                return false;
3440            }
3441
3442            intent.setComponent(new ComponentName(
3443                    aInfo.applicationInfo.packageName, aInfo.name));
3444            intent.setFlags(intent.getFlags()&~(
3445                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3446                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3447                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3448                    Intent.FLAG_ACTIVITY_NEW_TASK));
3449
3450            // Okay now we need to start the new activity, replacing the
3451            // currently running activity.  This is a little tricky because
3452            // we want to start the new one as if the current one is finished,
3453            // but not finish the current one first so that there is no flicker.
3454            // And thus...
3455            final boolean wasFinishing = r.finishing;
3456            r.finishing = true;
3457
3458            // Propagate reply information over to the new activity.
3459            final ActivityRecord resultTo = r.resultTo;
3460            final String resultWho = r.resultWho;
3461            final int requestCode = r.requestCode;
3462            r.resultTo = null;
3463            if (resultTo != null) {
3464                resultTo.removeResultsLocked(r, resultWho, requestCode);
3465            }
3466
3467            final long origId = Binder.clearCallingIdentity();
3468            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3469                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3470                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3471                    options, false, null, null);
3472            Binder.restoreCallingIdentity(origId);
3473
3474            r.finishing = wasFinishing;
3475            if (res != ActivityManager.START_SUCCESS) {
3476                return false;
3477            }
3478            return true;
3479        }
3480    }
3481
3482    final int startActivityInPackage(int uid, String callingPackage,
3483            Intent intent, String resolvedType, IBinder resultTo,
3484            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3485                    IActivityContainer container) {
3486
3487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3488                false, true, "startActivityInPackage", null);
3489
3490        // TODO: Switch to user app stacks here.
3491        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3492                null, null, resultTo, resultWho, requestCode, startFlags,
3493                null, null, null, null, options, userId, container);
3494        return ret;
3495    }
3496
3497    @Override
3498    public final int startActivities(IApplicationThread caller, String callingPackage,
3499            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3500            int userId) {
3501        enforceNotIsolatedCaller("startActivities");
3502        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3503                false, true, "startActivity", null);
3504        // TODO: Switch to user app stacks here.
3505        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3506                resolvedTypes, resultTo, options, userId);
3507        return ret;
3508    }
3509
3510    final int startActivitiesInPackage(int uid, String callingPackage,
3511            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3512            Bundle options, int userId) {
3513
3514        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3515                false, true, "startActivityInPackage", null);
3516        // TODO: Switch to user app stacks here.
3517        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3518                resultTo, options, userId);
3519        return ret;
3520    }
3521
3522    final void addRecentTaskLocked(TaskRecord task) {
3523        int N = mRecentTasks.size();
3524        // Quick case: check if the top-most recent task is the same.
3525        if (N > 0 && mRecentTasks.get(0) == task) {
3526            return;
3527        }
3528        // Another quick case: never add voice sessions.
3529        if (task.voiceSession != null) {
3530            return;
3531        }
3532        // Remove any existing entries that are the same kind of task.
3533        final Intent intent = task.intent;
3534        final boolean document = intent != null && intent.isDocument();
3535        for (int i=0; i<N; i++) {
3536            TaskRecord tr = mRecentTasks.get(i);
3537            if (task != tr) {
3538                if (task.userId != tr.userId) {
3539                    continue;
3540                }
3541                final Intent trIntent = tr.intent;
3542                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3543                    (intent == null || !intent.filterEquals(trIntent))) {
3544                    continue;
3545                }
3546                if (document || trIntent != null && trIntent.isDocument()) {
3547                    // Document tasks do not match other tasks.
3548                    continue;
3549                }
3550            }
3551
3552            // Either task and tr are the same or, their affinities match or their intents match
3553            // and neither of them is a document.
3554            tr.disposeThumbnail();
3555            mRecentTasks.remove(i);
3556            i--;
3557            N--;
3558            if (task.intent == null) {
3559                // If the new recent task we are adding is not fully
3560                // specified, then replace it with the existing recent task.
3561                task = tr;
3562            }
3563        }
3564        if (N >= MAX_RECENT_TASKS) {
3565            mRecentTasks.remove(N-1).disposeThumbnail();
3566        }
3567        mRecentTasks.add(0, task);
3568    }
3569
3570    @Override
3571    public void reportActivityFullyDrawn(IBinder token) {
3572        synchronized (this) {
3573            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3574            if (r == null) {
3575                return;
3576            }
3577            r.reportFullyDrawnLocked();
3578        }
3579    }
3580
3581    @Override
3582    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3583        synchronized (this) {
3584            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3585            if (r == null) {
3586                return;
3587            }
3588            final long origId = Binder.clearCallingIdentity();
3589            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3590            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3591                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3592            if (config != null) {
3593                r.frozenBeforeDestroy = true;
3594                if (!updateConfigurationLocked(config, r, false, false)) {
3595                    mStackSupervisor.resumeTopActivitiesLocked();
3596                }
3597            }
3598            Binder.restoreCallingIdentity(origId);
3599        }
3600    }
3601
3602    @Override
3603    public int getRequestedOrientation(IBinder token) {
3604        synchronized (this) {
3605            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3606            if (r == null) {
3607                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3608            }
3609            return mWindowManager.getAppOrientation(r.appToken);
3610        }
3611    }
3612
3613    /**
3614     * This is the internal entry point for handling Activity.finish().
3615     *
3616     * @param token The Binder token referencing the Activity we want to finish.
3617     * @param resultCode Result code, if any, from this Activity.
3618     * @param resultData Result data (Intent), if any, from this Activity.
3619     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3620     *            the root Activity in the task.
3621     *
3622     * @return Returns true if the activity successfully finished, or false if it is still running.
3623     */
3624    @Override
3625    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3626            boolean finishTask) {
3627        // Refuse possible leaked file descriptors
3628        if (resultData != null && resultData.hasFileDescriptors() == true) {
3629            throw new IllegalArgumentException("File descriptors passed in Intent");
3630        }
3631
3632        synchronized(this) {
3633            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3634            if (r == null) {
3635                return true;
3636            }
3637            // Keep track of the root activity of the task before we finish it
3638            TaskRecord tr = r.task;
3639            ActivityRecord rootR = tr.getRootActivity();
3640            if (mController != null) {
3641                // Find the first activity that is not finishing.
3642                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3643                if (next != null) {
3644                    // ask watcher if this is allowed
3645                    boolean resumeOK = true;
3646                    try {
3647                        resumeOK = mController.activityResuming(next.packageName);
3648                    } catch (RemoteException e) {
3649                        mController = null;
3650                        Watchdog.getInstance().setActivityController(null);
3651                    }
3652
3653                    if (!resumeOK) {
3654                        return false;
3655                    }
3656                }
3657            }
3658            final long origId = Binder.clearCallingIdentity();
3659            try {
3660                boolean res;
3661                if (finishTask && r == rootR) {
3662                    // If requested, remove the task that is associated to this activity only if it
3663                    // was the root activity in the task.  The result code and data is ignored because
3664                    // we don't support returning them across task boundaries.
3665                    res = removeTaskByIdLocked(tr.taskId, 0);
3666                } else {
3667                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3668                            resultData, "app-request", true);
3669                }
3670                return res;
3671            } finally {
3672                Binder.restoreCallingIdentity(origId);
3673            }
3674        }
3675    }
3676
3677    @Override
3678    public final void finishHeavyWeightApp() {
3679        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3680                != PackageManager.PERMISSION_GRANTED) {
3681            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3682                    + Binder.getCallingPid()
3683                    + ", uid=" + Binder.getCallingUid()
3684                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3685            Slog.w(TAG, msg);
3686            throw new SecurityException(msg);
3687        }
3688
3689        synchronized(this) {
3690            if (mHeavyWeightProcess == null) {
3691                return;
3692            }
3693
3694            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3695                    mHeavyWeightProcess.activities);
3696            for (int i=0; i<activities.size(); i++) {
3697                ActivityRecord r = activities.get(i);
3698                if (!r.finishing) {
3699                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3700                            null, "finish-heavy", true);
3701                }
3702            }
3703
3704            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3705                    mHeavyWeightProcess.userId, 0));
3706            mHeavyWeightProcess = null;
3707        }
3708    }
3709
3710    @Override
3711    public void crashApplication(int uid, int initialPid, String packageName,
3712            String message) {
3713        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3714                != PackageManager.PERMISSION_GRANTED) {
3715            String msg = "Permission Denial: crashApplication() from pid="
3716                    + Binder.getCallingPid()
3717                    + ", uid=" + Binder.getCallingUid()
3718                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3719            Slog.w(TAG, msg);
3720            throw new SecurityException(msg);
3721        }
3722
3723        synchronized(this) {
3724            ProcessRecord proc = null;
3725
3726            // Figure out which process to kill.  We don't trust that initialPid
3727            // still has any relation to current pids, so must scan through the
3728            // list.
3729            synchronized (mPidsSelfLocked) {
3730                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3731                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3732                    if (p.uid != uid) {
3733                        continue;
3734                    }
3735                    if (p.pid == initialPid) {
3736                        proc = p;
3737                        break;
3738                    }
3739                    if (p.pkgList.containsKey(packageName)) {
3740                        proc = p;
3741                    }
3742                }
3743            }
3744
3745            if (proc == null) {
3746                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3747                        + " initialPid=" + initialPid
3748                        + " packageName=" + packageName);
3749                return;
3750            }
3751
3752            if (proc.thread != null) {
3753                if (proc.pid == Process.myPid()) {
3754                    Log.w(TAG, "crashApplication: trying to crash self!");
3755                    return;
3756                }
3757                long ident = Binder.clearCallingIdentity();
3758                try {
3759                    proc.thread.scheduleCrash(message);
3760                } catch (RemoteException e) {
3761                }
3762                Binder.restoreCallingIdentity(ident);
3763            }
3764        }
3765    }
3766
3767    @Override
3768    public final void finishSubActivity(IBinder token, String resultWho,
3769            int requestCode) {
3770        synchronized(this) {
3771            final long origId = Binder.clearCallingIdentity();
3772            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3773            if (r != null) {
3774                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3775            }
3776            Binder.restoreCallingIdentity(origId);
3777        }
3778    }
3779
3780    @Override
3781    public boolean finishActivityAffinity(IBinder token) {
3782        synchronized(this) {
3783            final long origId = Binder.clearCallingIdentity();
3784            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3785            boolean res = false;
3786            if (r != null) {
3787                res = r.task.stack.finishActivityAffinityLocked(r);
3788            }
3789            Binder.restoreCallingIdentity(origId);
3790            return res;
3791        }
3792    }
3793
3794    @Override
3795    public boolean willActivityBeVisible(IBinder token) {
3796        synchronized(this) {
3797            ActivityStack stack = ActivityRecord.getStackLocked(token);
3798            if (stack != null) {
3799                return stack.willActivityBeVisibleLocked(token);
3800            }
3801            return false;
3802        }
3803    }
3804
3805    @Override
3806    public void overridePendingTransition(IBinder token, String packageName,
3807            int enterAnim, int exitAnim) {
3808        synchronized(this) {
3809            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3810            if (self == null) {
3811                return;
3812            }
3813
3814            final long origId = Binder.clearCallingIdentity();
3815
3816            if (self.state == ActivityState.RESUMED
3817                    || self.state == ActivityState.PAUSING) {
3818                mWindowManager.overridePendingAppTransition(packageName,
3819                        enterAnim, exitAnim, null);
3820            }
3821
3822            Binder.restoreCallingIdentity(origId);
3823        }
3824    }
3825
3826    /**
3827     * Main function for removing an existing process from the activity manager
3828     * as a result of that process going away.  Clears out all connections
3829     * to the process.
3830     */
3831    private final void handleAppDiedLocked(ProcessRecord app,
3832            boolean restarting, boolean allowRestart) {
3833        int pid = app.pid;
3834        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3835        if (!restarting) {
3836            removeLruProcessLocked(app);
3837            if (pid > 0) {
3838                ProcessList.remove(pid);
3839            }
3840        }
3841
3842        if (mProfileProc == app) {
3843            clearProfilerLocked();
3844        }
3845
3846        // Remove this application's activities from active lists.
3847        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3848
3849        app.activities.clear();
3850
3851        if (app.instrumentationClass != null) {
3852            Slog.w(TAG, "Crash of app " + app.processName
3853                  + " running instrumentation " + app.instrumentationClass);
3854            Bundle info = new Bundle();
3855            info.putString("shortMsg", "Process crashed.");
3856            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3857        }
3858
3859        if (!restarting) {
3860            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3861                // If there was nothing to resume, and we are not already
3862                // restarting this process, but there is a visible activity that
3863                // is hosted by the process...  then make sure all visible
3864                // activities are running, taking care of restarting this
3865                // process.
3866                if (hasVisibleActivities) {
3867                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3868                }
3869            }
3870        }
3871    }
3872
3873    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3874        IBinder threadBinder = thread.asBinder();
3875        // Find the application record.
3876        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3877            ProcessRecord rec = mLruProcesses.get(i);
3878            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3879                return i;
3880            }
3881        }
3882        return -1;
3883    }
3884
3885    final ProcessRecord getRecordForAppLocked(
3886            IApplicationThread thread) {
3887        if (thread == null) {
3888            return null;
3889        }
3890
3891        int appIndex = getLRURecordIndexForAppLocked(thread);
3892        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3893    }
3894
3895    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3896        // If there are no longer any background processes running,
3897        // and the app that died was not running instrumentation,
3898        // then tell everyone we are now low on memory.
3899        boolean haveBg = false;
3900        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3901            ProcessRecord rec = mLruProcesses.get(i);
3902            if (rec.thread != null
3903                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3904                haveBg = true;
3905                break;
3906            }
3907        }
3908
3909        if (!haveBg) {
3910            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3911            if (doReport) {
3912                long now = SystemClock.uptimeMillis();
3913                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3914                    doReport = false;
3915                } else {
3916                    mLastMemUsageReportTime = now;
3917                }
3918            }
3919            final ArrayList<ProcessMemInfo> memInfos
3920                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3921            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3922            long now = SystemClock.uptimeMillis();
3923            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3924                ProcessRecord rec = mLruProcesses.get(i);
3925                if (rec == dyingProc || rec.thread == null) {
3926                    continue;
3927                }
3928                if (doReport) {
3929                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3930                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3931                }
3932                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3933                    // The low memory report is overriding any current
3934                    // state for a GC request.  Make sure to do
3935                    // heavy/important/visible/foreground processes first.
3936                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3937                        rec.lastRequestedGc = 0;
3938                    } else {
3939                        rec.lastRequestedGc = rec.lastLowMemory;
3940                    }
3941                    rec.reportLowMemory = true;
3942                    rec.lastLowMemory = now;
3943                    mProcessesToGc.remove(rec);
3944                    addProcessToGcListLocked(rec);
3945                }
3946            }
3947            if (doReport) {
3948                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3949                mHandler.sendMessage(msg);
3950            }
3951            scheduleAppGcsLocked();
3952        }
3953    }
3954
3955    final void appDiedLocked(ProcessRecord app, int pid,
3956            IApplicationThread thread) {
3957
3958        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3959        synchronized (stats) {
3960            stats.noteProcessDiedLocked(app.info.uid, pid);
3961        }
3962
3963        // Clean up already done if the process has been re-started.
3964        if (app.pid == pid && app.thread != null &&
3965                app.thread.asBinder() == thread.asBinder()) {
3966            boolean doLowMem = app.instrumentationClass == null;
3967            boolean doOomAdj = doLowMem;
3968            if (!app.killedByAm) {
3969                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3970                        + ") has died.");
3971                mAllowLowerMemLevel = true;
3972            } else {
3973                // Note that we always want to do oom adj to update our state with the
3974                // new number of procs.
3975                mAllowLowerMemLevel = false;
3976                doLowMem = false;
3977            }
3978            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3979            if (DEBUG_CLEANUP) Slog.v(
3980                TAG, "Dying app: " + app + ", pid: " + pid
3981                + ", thread: " + thread.asBinder());
3982            handleAppDiedLocked(app, false, true);
3983
3984            if (doOomAdj) {
3985                updateOomAdjLocked();
3986            }
3987            if (doLowMem) {
3988                doLowMemReportIfNeededLocked(app);
3989            }
3990        } else if (app.pid != pid) {
3991            // A new process has already been started.
3992            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3993                    + ") has died and restarted (pid " + app.pid + ").");
3994            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3995        } else if (DEBUG_PROCESSES) {
3996            Slog.d(TAG, "Received spurious death notification for thread "
3997                    + thread.asBinder());
3998        }
3999    }
4000
4001    /**
4002     * If a stack trace dump file is configured, dump process stack traces.
4003     * @param clearTraces causes the dump file to be erased prior to the new
4004     *    traces being written, if true; when false, the new traces will be
4005     *    appended to any existing file content.
4006     * @param firstPids of dalvik VM processes to dump stack traces for first
4007     * @param lastPids of dalvik VM processes to dump stack traces for last
4008     * @param nativeProcs optional list of native process names to dump stack crawls
4009     * @return file containing stack traces, or null if no dump file is configured
4010     */
4011    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4012            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4013        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4014        if (tracesPath == null || tracesPath.length() == 0) {
4015            return null;
4016        }
4017
4018        File tracesFile = new File(tracesPath);
4019        try {
4020            File tracesDir = tracesFile.getParentFile();
4021            if (!tracesDir.exists()) {
4022                tracesFile.mkdirs();
4023                if (!SELinux.restorecon(tracesDir)) {
4024                    return null;
4025                }
4026            }
4027            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4028
4029            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4030            tracesFile.createNewFile();
4031            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4032        } catch (IOException e) {
4033            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4034            return null;
4035        }
4036
4037        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4038        return tracesFile;
4039    }
4040
4041    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4042            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4043        // Use a FileObserver to detect when traces finish writing.
4044        // The order of traces is considered important to maintain for legibility.
4045        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4046            @Override
4047            public synchronized void onEvent(int event, String path) { notify(); }
4048        };
4049
4050        try {
4051            observer.startWatching();
4052
4053            // First collect all of the stacks of the most important pids.
4054            if (firstPids != null) {
4055                try {
4056                    int num = firstPids.size();
4057                    for (int i = 0; i < num; i++) {
4058                        synchronized (observer) {
4059                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4060                            observer.wait(200);  // Wait for write-close, give up after 200msec
4061                        }
4062                    }
4063                } catch (InterruptedException e) {
4064                    Log.wtf(TAG, e);
4065                }
4066            }
4067
4068            // Next collect the stacks of the native pids
4069            if (nativeProcs != null) {
4070                int[] pids = Process.getPidsForCommands(nativeProcs);
4071                if (pids != null) {
4072                    for (int pid : pids) {
4073                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4074                    }
4075                }
4076            }
4077
4078            // Lastly, measure CPU usage.
4079            if (processCpuTracker != null) {
4080                processCpuTracker.init();
4081                System.gc();
4082                processCpuTracker.update();
4083                try {
4084                    synchronized (processCpuTracker) {
4085                        processCpuTracker.wait(500); // measure over 1/2 second.
4086                    }
4087                } catch (InterruptedException e) {
4088                }
4089                processCpuTracker.update();
4090
4091                // We'll take the stack crawls of just the top apps using CPU.
4092                final int N = processCpuTracker.countWorkingStats();
4093                int numProcs = 0;
4094                for (int i=0; i<N && numProcs<5; i++) {
4095                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4096                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4097                        numProcs++;
4098                        try {
4099                            synchronized (observer) {
4100                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4101                                observer.wait(200);  // Wait for write-close, give up after 200msec
4102                            }
4103                        } catch (InterruptedException e) {
4104                            Log.wtf(TAG, e);
4105                        }
4106
4107                    }
4108                }
4109            }
4110        } finally {
4111            observer.stopWatching();
4112        }
4113    }
4114
4115    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4116        if (true || IS_USER_BUILD) {
4117            return;
4118        }
4119        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4120        if (tracesPath == null || tracesPath.length() == 0) {
4121            return;
4122        }
4123
4124        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4125        StrictMode.allowThreadDiskWrites();
4126        try {
4127            final File tracesFile = new File(tracesPath);
4128            final File tracesDir = tracesFile.getParentFile();
4129            final File tracesTmp = new File(tracesDir, "__tmp__");
4130            try {
4131                if (!tracesDir.exists()) {
4132                    tracesFile.mkdirs();
4133                    if (!SELinux.restorecon(tracesDir.getPath())) {
4134                        return;
4135                    }
4136                }
4137                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4138
4139                if (tracesFile.exists()) {
4140                    tracesTmp.delete();
4141                    tracesFile.renameTo(tracesTmp);
4142                }
4143                StringBuilder sb = new StringBuilder();
4144                Time tobj = new Time();
4145                tobj.set(System.currentTimeMillis());
4146                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4147                sb.append(": ");
4148                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4149                sb.append(" since ");
4150                sb.append(msg);
4151                FileOutputStream fos = new FileOutputStream(tracesFile);
4152                fos.write(sb.toString().getBytes());
4153                if (app == null) {
4154                    fos.write("\n*** No application process!".getBytes());
4155                }
4156                fos.close();
4157                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4158            } catch (IOException e) {
4159                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4160                return;
4161            }
4162
4163            if (app != null) {
4164                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4165                firstPids.add(app.pid);
4166                dumpStackTraces(tracesPath, firstPids, null, null, null);
4167            }
4168
4169            File lastTracesFile = null;
4170            File curTracesFile = null;
4171            for (int i=9; i>=0; i--) {
4172                String name = String.format(Locale.US, "slow%02d.txt", i);
4173                curTracesFile = new File(tracesDir, name);
4174                if (curTracesFile.exists()) {
4175                    if (lastTracesFile != null) {
4176                        curTracesFile.renameTo(lastTracesFile);
4177                    } else {
4178                        curTracesFile.delete();
4179                    }
4180                }
4181                lastTracesFile = curTracesFile;
4182            }
4183            tracesFile.renameTo(curTracesFile);
4184            if (tracesTmp.exists()) {
4185                tracesTmp.renameTo(tracesFile);
4186            }
4187        } finally {
4188            StrictMode.setThreadPolicy(oldPolicy);
4189        }
4190    }
4191
4192    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4193            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4194        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4195        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4196
4197        if (mController != null) {
4198            try {
4199                // 0 == continue, -1 = kill process immediately
4200                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4201                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4202            } catch (RemoteException e) {
4203                mController = null;
4204                Watchdog.getInstance().setActivityController(null);
4205            }
4206        }
4207
4208        long anrTime = SystemClock.uptimeMillis();
4209        if (MONITOR_CPU_USAGE) {
4210            updateCpuStatsNow();
4211        }
4212
4213        synchronized (this) {
4214            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4215            if (mShuttingDown) {
4216                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4217                return;
4218            } else if (app.notResponding) {
4219                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4220                return;
4221            } else if (app.crashing) {
4222                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4223                return;
4224            }
4225
4226            // In case we come through here for the same app before completing
4227            // this one, mark as anring now so we will bail out.
4228            app.notResponding = true;
4229
4230            // Log the ANR to the event log.
4231            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4232                    app.processName, app.info.flags, annotation);
4233
4234            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4235            firstPids.add(app.pid);
4236
4237            int parentPid = app.pid;
4238            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4239            if (parentPid != app.pid) firstPids.add(parentPid);
4240
4241            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4242
4243            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4244                ProcessRecord r = mLruProcesses.get(i);
4245                if (r != null && r.thread != null) {
4246                    int pid = r.pid;
4247                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4248                        if (r.persistent) {
4249                            firstPids.add(pid);
4250                        } else {
4251                            lastPids.put(pid, Boolean.TRUE);
4252                        }
4253                    }
4254                }
4255            }
4256        }
4257
4258        // Log the ANR to the main log.
4259        StringBuilder info = new StringBuilder();
4260        info.setLength(0);
4261        info.append("ANR in ").append(app.processName);
4262        if (activity != null && activity.shortComponentName != null) {
4263            info.append(" (").append(activity.shortComponentName).append(")");
4264        }
4265        info.append("\n");
4266        info.append("PID: ").append(app.pid).append("\n");
4267        if (annotation != null) {
4268            info.append("Reason: ").append(annotation).append("\n");
4269        }
4270        if (parent != null && parent != activity) {
4271            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4272        }
4273
4274        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4275
4276        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4277                NATIVE_STACKS_OF_INTEREST);
4278
4279        String cpuInfo = null;
4280        if (MONITOR_CPU_USAGE) {
4281            updateCpuStatsNow();
4282            synchronized (mProcessCpuThread) {
4283                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4284            }
4285            info.append(processCpuTracker.printCurrentLoad());
4286            info.append(cpuInfo);
4287        }
4288
4289        info.append(processCpuTracker.printCurrentState(anrTime));
4290
4291        Slog.e(TAG, info.toString());
4292        if (tracesFile == null) {
4293            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4294            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4295        }
4296
4297        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4298                cpuInfo, tracesFile, null);
4299
4300        if (mController != null) {
4301            try {
4302                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4303                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4304                if (res != 0) {
4305                    if (res < 0 && app.pid != MY_PID) {
4306                        Process.killProcess(app.pid);
4307                    } else {
4308                        synchronized (this) {
4309                            mServices.scheduleServiceTimeoutLocked(app);
4310                        }
4311                    }
4312                    return;
4313                }
4314            } catch (RemoteException e) {
4315                mController = null;
4316                Watchdog.getInstance().setActivityController(null);
4317            }
4318        }
4319
4320        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4321        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4322                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4323
4324        synchronized (this) {
4325            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4326                killUnneededProcessLocked(app, "background ANR");
4327                return;
4328            }
4329
4330            // Set the app's notResponding state, and look up the errorReportReceiver
4331            makeAppNotRespondingLocked(app,
4332                    activity != null ? activity.shortComponentName : null,
4333                    annotation != null ? "ANR " + annotation : "ANR",
4334                    info.toString());
4335
4336            // Bring up the infamous App Not Responding dialog
4337            Message msg = Message.obtain();
4338            HashMap<String, Object> map = new HashMap<String, Object>();
4339            msg.what = SHOW_NOT_RESPONDING_MSG;
4340            msg.obj = map;
4341            msg.arg1 = aboveSystem ? 1 : 0;
4342            map.put("app", app);
4343            if (activity != null) {
4344                map.put("activity", activity);
4345            }
4346
4347            mHandler.sendMessage(msg);
4348        }
4349    }
4350
4351    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4352        if (!mLaunchWarningShown) {
4353            mLaunchWarningShown = true;
4354            mHandler.post(new Runnable() {
4355                @Override
4356                public void run() {
4357                    synchronized (ActivityManagerService.this) {
4358                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4359                        d.show();
4360                        mHandler.postDelayed(new Runnable() {
4361                            @Override
4362                            public void run() {
4363                                synchronized (ActivityManagerService.this) {
4364                                    d.dismiss();
4365                                    mLaunchWarningShown = false;
4366                                }
4367                            }
4368                        }, 4000);
4369                    }
4370                }
4371            });
4372        }
4373    }
4374
4375    @Override
4376    public boolean clearApplicationUserData(final String packageName,
4377            final IPackageDataObserver observer, int userId) {
4378        enforceNotIsolatedCaller("clearApplicationUserData");
4379        int uid = Binder.getCallingUid();
4380        int pid = Binder.getCallingPid();
4381        userId = handleIncomingUser(pid, uid,
4382                userId, false, true, "clearApplicationUserData", null);
4383        long callingId = Binder.clearCallingIdentity();
4384        try {
4385            IPackageManager pm = AppGlobals.getPackageManager();
4386            int pkgUid = -1;
4387            synchronized(this) {
4388                try {
4389                    pkgUid = pm.getPackageUid(packageName, userId);
4390                } catch (RemoteException e) {
4391                }
4392                if (pkgUid == -1) {
4393                    Slog.w(TAG, "Invalid packageName: " + packageName);
4394                    if (observer != null) {
4395                        try {
4396                            observer.onRemoveCompleted(packageName, false);
4397                        } catch (RemoteException e) {
4398                            Slog.i(TAG, "Observer no longer exists.");
4399                        }
4400                    }
4401                    return false;
4402                }
4403                if (uid == pkgUid || checkComponentPermission(
4404                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4405                        pid, uid, -1, true)
4406                        == PackageManager.PERMISSION_GRANTED) {
4407                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4408                } else {
4409                    throw new SecurityException("PID " + pid + " does not have permission "
4410                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4411                                    + " of package " + packageName);
4412                }
4413            }
4414
4415            try {
4416                // Clear application user data
4417                pm.clearApplicationUserData(packageName, observer, userId);
4418
4419                // Remove all permissions granted from/to this package
4420                removeUriPermissionsForPackageLocked(packageName, userId, true);
4421
4422                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4423                        Uri.fromParts("package", packageName, null));
4424                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4425                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4426                        null, null, 0, null, null, null, false, false, userId);
4427            } catch (RemoteException e) {
4428            }
4429        } finally {
4430            Binder.restoreCallingIdentity(callingId);
4431        }
4432        return true;
4433    }
4434
4435    @Override
4436    public void killBackgroundProcesses(final String packageName, int userId) {
4437        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4438                != PackageManager.PERMISSION_GRANTED &&
4439                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4440                        != PackageManager.PERMISSION_GRANTED) {
4441            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4442                    + Binder.getCallingPid()
4443                    + ", uid=" + Binder.getCallingUid()
4444                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4445            Slog.w(TAG, msg);
4446            throw new SecurityException(msg);
4447        }
4448
4449        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4450                userId, true, true, "killBackgroundProcesses", null);
4451        long callingId = Binder.clearCallingIdentity();
4452        try {
4453            IPackageManager pm = AppGlobals.getPackageManager();
4454            synchronized(this) {
4455                int appId = -1;
4456                try {
4457                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4458                } catch (RemoteException e) {
4459                }
4460                if (appId == -1) {
4461                    Slog.w(TAG, "Invalid packageName: " + packageName);
4462                    return;
4463                }
4464                killPackageProcessesLocked(packageName, appId, userId,
4465                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4466            }
4467        } finally {
4468            Binder.restoreCallingIdentity(callingId);
4469        }
4470    }
4471
4472    @Override
4473    public void killAllBackgroundProcesses() {
4474        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4475                != PackageManager.PERMISSION_GRANTED) {
4476            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4477                    + Binder.getCallingPid()
4478                    + ", uid=" + Binder.getCallingUid()
4479                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4480            Slog.w(TAG, msg);
4481            throw new SecurityException(msg);
4482        }
4483
4484        long callingId = Binder.clearCallingIdentity();
4485        try {
4486            synchronized(this) {
4487                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4488                final int NP = mProcessNames.getMap().size();
4489                for (int ip=0; ip<NP; ip++) {
4490                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4491                    final int NA = apps.size();
4492                    for (int ia=0; ia<NA; ia++) {
4493                        ProcessRecord app = apps.valueAt(ia);
4494                        if (app.persistent) {
4495                            // we don't kill persistent processes
4496                            continue;
4497                        }
4498                        if (app.removed) {
4499                            procs.add(app);
4500                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4501                            app.removed = true;
4502                            procs.add(app);
4503                        }
4504                    }
4505                }
4506
4507                int N = procs.size();
4508                for (int i=0; i<N; i++) {
4509                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4510                }
4511                mAllowLowerMemLevel = true;
4512                updateOomAdjLocked();
4513                doLowMemReportIfNeededLocked(null);
4514            }
4515        } finally {
4516            Binder.restoreCallingIdentity(callingId);
4517        }
4518    }
4519
4520    @Override
4521    public void forceStopPackage(final String packageName, int userId) {
4522        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4523                != PackageManager.PERMISSION_GRANTED) {
4524            String msg = "Permission Denial: forceStopPackage() from pid="
4525                    + Binder.getCallingPid()
4526                    + ", uid=" + Binder.getCallingUid()
4527                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4528            Slog.w(TAG, msg);
4529            throw new SecurityException(msg);
4530        }
4531        final int callingPid = Binder.getCallingPid();
4532        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4533                userId, true, true, "forceStopPackage", null);
4534        long callingId = Binder.clearCallingIdentity();
4535        try {
4536            IPackageManager pm = AppGlobals.getPackageManager();
4537            synchronized(this) {
4538                int[] users = userId == UserHandle.USER_ALL
4539                        ? getUsersLocked() : new int[] { userId };
4540                for (int user : users) {
4541                    int pkgUid = -1;
4542                    try {
4543                        pkgUid = pm.getPackageUid(packageName, user);
4544                    } catch (RemoteException e) {
4545                    }
4546                    if (pkgUid == -1) {
4547                        Slog.w(TAG, "Invalid packageName: " + packageName);
4548                        continue;
4549                    }
4550                    try {
4551                        pm.setPackageStoppedState(packageName, true, user);
4552                    } catch (RemoteException e) {
4553                    } catch (IllegalArgumentException e) {
4554                        Slog.w(TAG, "Failed trying to unstop package "
4555                                + packageName + ": " + e);
4556                    }
4557                    if (isUserRunningLocked(user, false)) {
4558                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4559                    }
4560                }
4561            }
4562        } finally {
4563            Binder.restoreCallingIdentity(callingId);
4564        }
4565    }
4566
4567    /*
4568     * The pkg name and app id have to be specified.
4569     */
4570    @Override
4571    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4572        if (pkg == null) {
4573            return;
4574        }
4575        // Make sure the uid is valid.
4576        if (appid < 0) {
4577            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4578            return;
4579        }
4580        int callerUid = Binder.getCallingUid();
4581        // Only the system server can kill an application
4582        if (callerUid == Process.SYSTEM_UID) {
4583            // Post an aysnc message to kill the application
4584            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4585            msg.arg1 = appid;
4586            msg.arg2 = 0;
4587            Bundle bundle = new Bundle();
4588            bundle.putString("pkg", pkg);
4589            bundle.putString("reason", reason);
4590            msg.obj = bundle;
4591            mHandler.sendMessage(msg);
4592        } else {
4593            throw new SecurityException(callerUid + " cannot kill pkg: " +
4594                    pkg);
4595        }
4596    }
4597
4598    @Override
4599    public void closeSystemDialogs(String reason) {
4600        enforceNotIsolatedCaller("closeSystemDialogs");
4601
4602        final int pid = Binder.getCallingPid();
4603        final int uid = Binder.getCallingUid();
4604        final long origId = Binder.clearCallingIdentity();
4605        try {
4606            synchronized (this) {
4607                // Only allow this from foreground processes, so that background
4608                // applications can't abuse it to prevent system UI from being shown.
4609                if (uid >= Process.FIRST_APPLICATION_UID) {
4610                    ProcessRecord proc;
4611                    synchronized (mPidsSelfLocked) {
4612                        proc = mPidsSelfLocked.get(pid);
4613                    }
4614                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4615                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4616                                + " from background process " + proc);
4617                        return;
4618                    }
4619                }
4620                closeSystemDialogsLocked(reason);
4621            }
4622        } finally {
4623            Binder.restoreCallingIdentity(origId);
4624        }
4625    }
4626
4627    void closeSystemDialogsLocked(String reason) {
4628        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4629        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4630                | Intent.FLAG_RECEIVER_FOREGROUND);
4631        if (reason != null) {
4632            intent.putExtra("reason", reason);
4633        }
4634        mWindowManager.closeSystemDialogs(reason);
4635
4636        mStackSupervisor.closeSystemDialogsLocked();
4637
4638        broadcastIntentLocked(null, null, intent, null,
4639                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4640                Process.SYSTEM_UID, UserHandle.USER_ALL);
4641    }
4642
4643    @Override
4644    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4645        enforceNotIsolatedCaller("getProcessMemoryInfo");
4646        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4647        for (int i=pids.length-1; i>=0; i--) {
4648            ProcessRecord proc;
4649            int oomAdj;
4650            synchronized (this) {
4651                synchronized (mPidsSelfLocked) {
4652                    proc = mPidsSelfLocked.get(pids[i]);
4653                    oomAdj = proc != null ? proc.setAdj : 0;
4654                }
4655            }
4656            infos[i] = new Debug.MemoryInfo();
4657            Debug.getMemoryInfo(pids[i], infos[i]);
4658            if (proc != null) {
4659                synchronized (this) {
4660                    if (proc.thread != null && proc.setAdj == oomAdj) {
4661                        // Record this for posterity if the process has been stable.
4662                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4663                                infos[i].getTotalUss(), false, proc.pkgList);
4664                    }
4665                }
4666            }
4667        }
4668        return infos;
4669    }
4670
4671    @Override
4672    public long[] getProcessPss(int[] pids) {
4673        enforceNotIsolatedCaller("getProcessPss");
4674        long[] pss = new long[pids.length];
4675        for (int i=pids.length-1; i>=0; i--) {
4676            ProcessRecord proc;
4677            int oomAdj;
4678            synchronized (this) {
4679                synchronized (mPidsSelfLocked) {
4680                    proc = mPidsSelfLocked.get(pids[i]);
4681                    oomAdj = proc != null ? proc.setAdj : 0;
4682                }
4683            }
4684            long[] tmpUss = new long[1];
4685            pss[i] = Debug.getPss(pids[i], tmpUss);
4686            if (proc != null) {
4687                synchronized (this) {
4688                    if (proc.thread != null && proc.setAdj == oomAdj) {
4689                        // Record this for posterity if the process has been stable.
4690                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4691                    }
4692                }
4693            }
4694        }
4695        return pss;
4696    }
4697
4698    @Override
4699    public void killApplicationProcess(String processName, int uid) {
4700        if (processName == null) {
4701            return;
4702        }
4703
4704        int callerUid = Binder.getCallingUid();
4705        // Only the system server can kill an application
4706        if (callerUid == Process.SYSTEM_UID) {
4707            synchronized (this) {
4708                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4709                if (app != null && app.thread != null) {
4710                    try {
4711                        app.thread.scheduleSuicide();
4712                    } catch (RemoteException e) {
4713                        // If the other end already died, then our work here is done.
4714                    }
4715                } else {
4716                    Slog.w(TAG, "Process/uid not found attempting kill of "
4717                            + processName + " / " + uid);
4718                }
4719            }
4720        } else {
4721            throw new SecurityException(callerUid + " cannot kill app process: " +
4722                    processName);
4723        }
4724    }
4725
4726    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4727        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4728                false, true, false, false, UserHandle.getUserId(uid), reason);
4729        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4730                Uri.fromParts("package", packageName, null));
4731        if (!mProcessesReady) {
4732            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4733                    | Intent.FLAG_RECEIVER_FOREGROUND);
4734        }
4735        intent.putExtra(Intent.EXTRA_UID, uid);
4736        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4737        broadcastIntentLocked(null, null, intent,
4738                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4739                false, false,
4740                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4741    }
4742
4743    private void forceStopUserLocked(int userId, String reason) {
4744        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4745        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4746        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4747                | Intent.FLAG_RECEIVER_FOREGROUND);
4748        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4749        broadcastIntentLocked(null, null, intent,
4750                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4751                false, false,
4752                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4753    }
4754
4755    private final boolean killPackageProcessesLocked(String packageName, int appId,
4756            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4757            boolean doit, boolean evenPersistent, String reason) {
4758        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4759
4760        // Remove all processes this package may have touched: all with the
4761        // same UID (except for the system or root user), and all whose name
4762        // matches the package name.
4763        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4764        final int NP = mProcessNames.getMap().size();
4765        for (int ip=0; ip<NP; ip++) {
4766            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4767            final int NA = apps.size();
4768            for (int ia=0; ia<NA; ia++) {
4769                ProcessRecord app = apps.valueAt(ia);
4770                if (app.persistent && !evenPersistent) {
4771                    // we don't kill persistent processes
4772                    continue;
4773                }
4774                if (app.removed) {
4775                    if (doit) {
4776                        procs.add(app);
4777                    }
4778                    continue;
4779                }
4780
4781                // Skip process if it doesn't meet our oom adj requirement.
4782                if (app.setAdj < minOomAdj) {
4783                    continue;
4784                }
4785
4786                // If no package is specified, we call all processes under the
4787                // give user id.
4788                if (packageName == null) {
4789                    if (app.userId != userId) {
4790                        continue;
4791                    }
4792                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4793                        continue;
4794                    }
4795                // Package has been specified, we want to hit all processes
4796                // that match it.  We need to qualify this by the processes
4797                // that are running under the specified app and user ID.
4798                } else {
4799                    if (UserHandle.getAppId(app.uid) != appId) {
4800                        continue;
4801                    }
4802                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4803                        continue;
4804                    }
4805                    if (!app.pkgList.containsKey(packageName)) {
4806                        continue;
4807                    }
4808                }
4809
4810                // Process has passed all conditions, kill it!
4811                if (!doit) {
4812                    return true;
4813                }
4814                app.removed = true;
4815                procs.add(app);
4816            }
4817        }
4818
4819        int N = procs.size();
4820        for (int i=0; i<N; i++) {
4821            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4822        }
4823        updateOomAdjLocked();
4824        return N > 0;
4825    }
4826
4827    private final boolean forceStopPackageLocked(String name, int appId,
4828            boolean callerWillRestart, boolean purgeCache, boolean doit,
4829            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4830        int i;
4831        int N;
4832
4833        if (userId == UserHandle.USER_ALL && name == null) {
4834            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4835        }
4836
4837        if (appId < 0 && name != null) {
4838            try {
4839                appId = UserHandle.getAppId(
4840                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4841            } catch (RemoteException e) {
4842            }
4843        }
4844
4845        if (doit) {
4846            if (name != null) {
4847                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4848                        + " user=" + userId + ": " + reason);
4849            } else {
4850                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4851            }
4852
4853            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4854            for (int ip=pmap.size()-1; ip>=0; ip--) {
4855                SparseArray<Long> ba = pmap.valueAt(ip);
4856                for (i=ba.size()-1; i>=0; i--) {
4857                    boolean remove = false;
4858                    final int entUid = ba.keyAt(i);
4859                    if (name != null) {
4860                        if (userId == UserHandle.USER_ALL) {
4861                            if (UserHandle.getAppId(entUid) == appId) {
4862                                remove = true;
4863                            }
4864                        } else {
4865                            if (entUid == UserHandle.getUid(userId, appId)) {
4866                                remove = true;
4867                            }
4868                        }
4869                    } else if (UserHandle.getUserId(entUid) == userId) {
4870                        remove = true;
4871                    }
4872                    if (remove) {
4873                        ba.removeAt(i);
4874                    }
4875                }
4876                if (ba.size() == 0) {
4877                    pmap.removeAt(ip);
4878                }
4879            }
4880        }
4881
4882        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4883                -100, callerWillRestart, true, doit, evenPersistent,
4884                name == null ? ("stop user " + userId) : ("stop " + name));
4885
4886        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4887            if (!doit) {
4888                return true;
4889            }
4890            didSomething = true;
4891        }
4892
4893        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4894            if (!doit) {
4895                return true;
4896            }
4897            didSomething = true;
4898        }
4899
4900        if (name == null) {
4901            // Remove all sticky broadcasts from this user.
4902            mStickyBroadcasts.remove(userId);
4903        }
4904
4905        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4906        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4907                userId, providers)) {
4908            if (!doit) {
4909                return true;
4910            }
4911            didSomething = true;
4912        }
4913        N = providers.size();
4914        for (i=0; i<N; i++) {
4915            removeDyingProviderLocked(null, providers.get(i), true);
4916        }
4917
4918        // Remove transient permissions granted from/to this package/user
4919        removeUriPermissionsForPackageLocked(name, userId, false);
4920
4921        if (name == null || uninstalling) {
4922            // Remove pending intents.  For now we only do this when force
4923            // stopping users, because we have some problems when doing this
4924            // for packages -- app widgets are not currently cleaned up for
4925            // such packages, so they can be left with bad pending intents.
4926            if (mIntentSenderRecords.size() > 0) {
4927                Iterator<WeakReference<PendingIntentRecord>> it
4928                        = mIntentSenderRecords.values().iterator();
4929                while (it.hasNext()) {
4930                    WeakReference<PendingIntentRecord> wpir = it.next();
4931                    if (wpir == null) {
4932                        it.remove();
4933                        continue;
4934                    }
4935                    PendingIntentRecord pir = wpir.get();
4936                    if (pir == null) {
4937                        it.remove();
4938                        continue;
4939                    }
4940                    if (name == null) {
4941                        // Stopping user, remove all objects for the user.
4942                        if (pir.key.userId != userId) {
4943                            // Not the same user, skip it.
4944                            continue;
4945                        }
4946                    } else {
4947                        if (UserHandle.getAppId(pir.uid) != appId) {
4948                            // Different app id, skip it.
4949                            continue;
4950                        }
4951                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4952                            // Different user, skip it.
4953                            continue;
4954                        }
4955                        if (!pir.key.packageName.equals(name)) {
4956                            // Different package, skip it.
4957                            continue;
4958                        }
4959                    }
4960                    if (!doit) {
4961                        return true;
4962                    }
4963                    didSomething = true;
4964                    it.remove();
4965                    pir.canceled = true;
4966                    if (pir.key.activity != null) {
4967                        pir.key.activity.pendingResults.remove(pir.ref);
4968                    }
4969                }
4970            }
4971        }
4972
4973        if (doit) {
4974            if (purgeCache && name != null) {
4975                AttributeCache ac = AttributeCache.instance();
4976                if (ac != null) {
4977                    ac.removePackage(name);
4978                }
4979            }
4980            if (mBooted) {
4981                mStackSupervisor.resumeTopActivitiesLocked();
4982                mStackSupervisor.scheduleIdleLocked();
4983            }
4984        }
4985
4986        return didSomething;
4987    }
4988
4989    private final boolean removeProcessLocked(ProcessRecord app,
4990            boolean callerWillRestart, boolean allowRestart, String reason) {
4991        final String name = app.processName;
4992        final int uid = app.uid;
4993        if (DEBUG_PROCESSES) Slog.d(
4994            TAG, "Force removing proc " + app.toShortString() + " (" + name
4995            + "/" + uid + ")");
4996
4997        mProcessNames.remove(name, uid);
4998        mIsolatedProcesses.remove(app.uid);
4999        if (mHeavyWeightProcess == app) {
5000            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5001                    mHeavyWeightProcess.userId, 0));
5002            mHeavyWeightProcess = null;
5003        }
5004        boolean needRestart = false;
5005        if (app.pid > 0 && app.pid != MY_PID) {
5006            int pid = app.pid;
5007            synchronized (mPidsSelfLocked) {
5008                mPidsSelfLocked.remove(pid);
5009                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5010            }
5011            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5012                    app.processName, app.info.uid);
5013            if (app.isolated) {
5014                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5015            }
5016            killUnneededProcessLocked(app, reason);
5017            handleAppDiedLocked(app, true, allowRestart);
5018            removeLruProcessLocked(app);
5019
5020            if (app.persistent && !app.isolated) {
5021                if (!callerWillRestart) {
5022                    addAppLocked(app.info, false);
5023                } else {
5024                    needRestart = true;
5025                }
5026            }
5027        } else {
5028            mRemovedProcesses.add(app);
5029        }
5030
5031        return needRestart;
5032    }
5033
5034    private final void processStartTimedOutLocked(ProcessRecord app) {
5035        final int pid = app.pid;
5036        boolean gone = false;
5037        synchronized (mPidsSelfLocked) {
5038            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5039            if (knownApp != null && knownApp.thread == null) {
5040                mPidsSelfLocked.remove(pid);
5041                gone = true;
5042            }
5043        }
5044
5045        if (gone) {
5046            Slog.w(TAG, "Process " + app + " failed to attach");
5047            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5048                    pid, app.uid, app.processName);
5049            mProcessNames.remove(app.processName, app.uid);
5050            mIsolatedProcesses.remove(app.uid);
5051            if (mHeavyWeightProcess == app) {
5052                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5053                        mHeavyWeightProcess.userId, 0));
5054                mHeavyWeightProcess = null;
5055            }
5056            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5057                    app.processName, app.info.uid);
5058            if (app.isolated) {
5059                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5060            }
5061            // Take care of any launching providers waiting for this process.
5062            checkAppInLaunchingProvidersLocked(app, true);
5063            // Take care of any services that are waiting for the process.
5064            mServices.processStartTimedOutLocked(app);
5065            killUnneededProcessLocked(app, "start timeout");
5066            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5067                Slog.w(TAG, "Unattached app died before backup, skipping");
5068                try {
5069                    IBackupManager bm = IBackupManager.Stub.asInterface(
5070                            ServiceManager.getService(Context.BACKUP_SERVICE));
5071                    bm.agentDisconnected(app.info.packageName);
5072                } catch (RemoteException e) {
5073                    // Can't happen; the backup manager is local
5074                }
5075            }
5076            if (isPendingBroadcastProcessLocked(pid)) {
5077                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5078                skipPendingBroadcastLocked(pid);
5079            }
5080        } else {
5081            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5082        }
5083    }
5084
5085    private final boolean attachApplicationLocked(IApplicationThread thread,
5086            int pid) {
5087
5088        // Find the application record that is being attached...  either via
5089        // the pid if we are running in multiple processes, or just pull the
5090        // next app record if we are emulating process with anonymous threads.
5091        ProcessRecord app;
5092        if (pid != MY_PID && pid >= 0) {
5093            synchronized (mPidsSelfLocked) {
5094                app = mPidsSelfLocked.get(pid);
5095            }
5096        } else {
5097            app = null;
5098        }
5099
5100        if (app == null) {
5101            Slog.w(TAG, "No pending application record for pid " + pid
5102                    + " (IApplicationThread " + thread + "); dropping process");
5103            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5104            if (pid > 0 && pid != MY_PID) {
5105                Process.killProcessQuiet(pid);
5106            } else {
5107                try {
5108                    thread.scheduleExit();
5109                } catch (Exception e) {
5110                    // Ignore exceptions.
5111                }
5112            }
5113            return false;
5114        }
5115
5116        // If this application record is still attached to a previous
5117        // process, clean it up now.
5118        if (app.thread != null) {
5119            handleAppDiedLocked(app, true, true);
5120        }
5121
5122        // Tell the process all about itself.
5123
5124        if (localLOGV) Slog.v(
5125                TAG, "Binding process pid " + pid + " to record " + app);
5126
5127        final String processName = app.processName;
5128        try {
5129            AppDeathRecipient adr = new AppDeathRecipient(
5130                    app, pid, thread);
5131            thread.asBinder().linkToDeath(adr, 0);
5132            app.deathRecipient = adr;
5133        } catch (RemoteException e) {
5134            app.resetPackageList(mProcessStats);
5135            startProcessLocked(app, "link fail", processName);
5136            return false;
5137        }
5138
5139        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5140
5141        app.makeActive(thread, mProcessStats);
5142        app.curAdj = app.setAdj = -100;
5143        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5144        app.forcingToForeground = null;
5145        updateProcessForegroundLocked(app, false, false);
5146        app.hasShownUi = false;
5147        app.debugging = false;
5148        app.cached = false;
5149
5150        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5151
5152        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5153        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5154
5155        if (!normalMode) {
5156            Slog.i(TAG, "Launching preboot mode app: " + app);
5157        }
5158
5159        if (localLOGV) Slog.v(
5160            TAG, "New app record " + app
5161            + " thread=" + thread.asBinder() + " pid=" + pid);
5162        try {
5163            int testMode = IApplicationThread.DEBUG_OFF;
5164            if (mDebugApp != null && mDebugApp.equals(processName)) {
5165                testMode = mWaitForDebugger
5166                    ? IApplicationThread.DEBUG_WAIT
5167                    : IApplicationThread.DEBUG_ON;
5168                app.debugging = true;
5169                if (mDebugTransient) {
5170                    mDebugApp = mOrigDebugApp;
5171                    mWaitForDebugger = mOrigWaitForDebugger;
5172                }
5173            }
5174            String profileFile = app.instrumentationProfileFile;
5175            ParcelFileDescriptor profileFd = null;
5176            boolean profileAutoStop = false;
5177            if (mProfileApp != null && mProfileApp.equals(processName)) {
5178                mProfileProc = app;
5179                profileFile = mProfileFile;
5180                profileFd = mProfileFd;
5181                profileAutoStop = mAutoStopProfiler;
5182            }
5183            boolean enableOpenGlTrace = false;
5184            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5185                enableOpenGlTrace = true;
5186                mOpenGlTraceApp = null;
5187            }
5188
5189            // If the app is being launched for restore or full backup, set it up specially
5190            boolean isRestrictedBackupMode = false;
5191            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5192                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5193                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5194                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5195            }
5196
5197            ensurePackageDexOpt(app.instrumentationInfo != null
5198                    ? app.instrumentationInfo.packageName
5199                    : app.info.packageName);
5200            if (app.instrumentationClass != null) {
5201                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5202            }
5203            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5204                    + processName + " with config " + mConfiguration);
5205            ApplicationInfo appInfo = app.instrumentationInfo != null
5206                    ? app.instrumentationInfo : app.info;
5207            app.compat = compatibilityInfoForPackageLocked(appInfo);
5208            if (profileFd != null) {
5209                profileFd = profileFd.dup();
5210            }
5211            thread.bindApplication(processName, appInfo, providers,
5212                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5213                    app.instrumentationArguments, app.instrumentationWatcher,
5214                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5215                    isRestrictedBackupMode || !normalMode, app.persistent,
5216                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5217                    mCoreSettingsObserver.getCoreSettingsLocked());
5218            updateLruProcessLocked(app, false, null);
5219            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5220        } catch (Exception e) {
5221            // todo: Yikes!  What should we do?  For now we will try to
5222            // start another process, but that could easily get us in
5223            // an infinite loop of restarting processes...
5224            Slog.w(TAG, "Exception thrown during bind!", e);
5225
5226            app.resetPackageList(mProcessStats);
5227            app.unlinkDeathRecipient();
5228            startProcessLocked(app, "bind fail", processName);
5229            return false;
5230        }
5231
5232        // Remove this record from the list of starting applications.
5233        mPersistentStartingProcesses.remove(app);
5234        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5235                "Attach application locked removing on hold: " + app);
5236        mProcessesOnHold.remove(app);
5237
5238        boolean badApp = false;
5239        boolean didSomething = false;
5240
5241        // See if the top visible activity is waiting to run in this process...
5242        if (normalMode) {
5243            try {
5244                if (mStackSupervisor.attachApplicationLocked(app)) {
5245                    didSomething = true;
5246                }
5247            } catch (Exception e) {
5248                badApp = true;
5249            }
5250        }
5251
5252        // Find any services that should be running in this process...
5253        if (!badApp) {
5254            try {
5255                didSomething |= mServices.attachApplicationLocked(app, processName);
5256            } catch (Exception e) {
5257                badApp = true;
5258            }
5259        }
5260
5261        // Check if a next-broadcast receiver is in this process...
5262        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5263            try {
5264                didSomething |= sendPendingBroadcastsLocked(app);
5265            } catch (Exception e) {
5266                // If the app died trying to launch the receiver we declare it 'bad'
5267                badApp = true;
5268            }
5269        }
5270
5271        // Check whether the next backup agent is in this process...
5272        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5273            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5274            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5275            try {
5276                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5277                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5278                        mBackupTarget.backupMode);
5279            } catch (Exception e) {
5280                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5281                e.printStackTrace();
5282            }
5283        }
5284
5285        if (badApp) {
5286            // todo: Also need to kill application to deal with all
5287            // kinds of exceptions.
5288            handleAppDiedLocked(app, false, true);
5289            return false;
5290        }
5291
5292        if (!didSomething) {
5293            updateOomAdjLocked();
5294        }
5295
5296        return true;
5297    }
5298
5299    @Override
5300    public final void attachApplication(IApplicationThread thread) {
5301        synchronized (this) {
5302            int callingPid = Binder.getCallingPid();
5303            final long origId = Binder.clearCallingIdentity();
5304            attachApplicationLocked(thread, callingPid);
5305            Binder.restoreCallingIdentity(origId);
5306        }
5307    }
5308
5309    @Override
5310    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5311        final long origId = Binder.clearCallingIdentity();
5312        synchronized (this) {
5313            ActivityStack stack = ActivityRecord.getStackLocked(token);
5314            if (stack != null) {
5315                ActivityRecord r =
5316                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5317                if (stopProfiling) {
5318                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5319                        try {
5320                            mProfileFd.close();
5321                        } catch (IOException e) {
5322                        }
5323                        clearProfilerLocked();
5324                    }
5325                }
5326            }
5327        }
5328        Binder.restoreCallingIdentity(origId);
5329    }
5330
5331    void enableScreenAfterBoot() {
5332        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5333                SystemClock.uptimeMillis());
5334        mWindowManager.enableScreenAfterBoot();
5335
5336        synchronized (this) {
5337            updateEventDispatchingLocked();
5338        }
5339    }
5340
5341    @Override
5342    public void showBootMessage(final CharSequence msg, final boolean always) {
5343        enforceNotIsolatedCaller("showBootMessage");
5344        mWindowManager.showBootMessage(msg, always);
5345    }
5346
5347    @Override
5348    public void dismissKeyguardOnNextActivity() {
5349        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5350        final long token = Binder.clearCallingIdentity();
5351        try {
5352            synchronized (this) {
5353                if (DEBUG_LOCKSCREEN) logLockScreen("");
5354                if (mLockScreenShown) {
5355                    mLockScreenShown = false;
5356                    comeOutOfSleepIfNeededLocked();
5357                }
5358                mStackSupervisor.setDismissKeyguard(true);
5359            }
5360        } finally {
5361            Binder.restoreCallingIdentity(token);
5362        }
5363    }
5364
5365    final void finishBooting() {
5366        // Register receivers to handle package update events
5367        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5368
5369        synchronized (this) {
5370            // Ensure that any processes we had put on hold are now started
5371            // up.
5372            final int NP = mProcessesOnHold.size();
5373            if (NP > 0) {
5374                ArrayList<ProcessRecord> procs =
5375                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5376                for (int ip=0; ip<NP; ip++) {
5377                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5378                            + procs.get(ip));
5379                    startProcessLocked(procs.get(ip), "on-hold", null);
5380                }
5381            }
5382
5383            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5384                // Start looking for apps that are abusing wake locks.
5385                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5386                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5387                // Tell anyone interested that we are done booting!
5388                SystemProperties.set("sys.boot_completed", "1");
5389                SystemProperties.set("dev.bootcomplete", "1");
5390                for (int i=0; i<mStartedUsers.size(); i++) {
5391                    UserStartedState uss = mStartedUsers.valueAt(i);
5392                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5393                        uss.mState = UserStartedState.STATE_RUNNING;
5394                        final int userId = mStartedUsers.keyAt(i);
5395                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5396                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5397                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5398                        broadcastIntentLocked(null, null, intent, null,
5399                                new IIntentReceiver.Stub() {
5400                                    @Override
5401                                    public void performReceive(Intent intent, int resultCode,
5402                                            String data, Bundle extras, boolean ordered,
5403                                            boolean sticky, int sendingUser) {
5404                                        synchronized (ActivityManagerService.this) {
5405                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5406                                                    true, false);
5407                                        }
5408                                    }
5409                                },
5410                                0, null, null,
5411                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5412                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5413                                userId);
5414                    }
5415                }
5416                scheduleStartProfilesLocked();
5417            }
5418        }
5419    }
5420
5421    final void ensureBootCompleted() {
5422        boolean booting;
5423        boolean enableScreen;
5424        synchronized (this) {
5425            booting = mBooting;
5426            mBooting = false;
5427            enableScreen = !mBooted;
5428            mBooted = true;
5429        }
5430
5431        if (booting) {
5432            finishBooting();
5433        }
5434
5435        if (enableScreen) {
5436            enableScreenAfterBoot();
5437        }
5438    }
5439
5440    @Override
5441    public final void activityResumed(IBinder token) {
5442        final long origId = Binder.clearCallingIdentity();
5443        synchronized(this) {
5444            ActivityStack stack = ActivityRecord.getStackLocked(token);
5445            if (stack != null) {
5446                ActivityRecord.activityResumedLocked(token);
5447            }
5448        }
5449        Binder.restoreCallingIdentity(origId);
5450    }
5451
5452    @Override
5453    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5454        final long origId = Binder.clearCallingIdentity();
5455        synchronized(this) {
5456            ActivityStack stack = ActivityRecord.getStackLocked(token);
5457            if (stack != null) {
5458                stack.activityPausedLocked(token, false, persistentState);
5459            }
5460        }
5461        Binder.restoreCallingIdentity(origId);
5462    }
5463
5464    @Override
5465    public final void activityStopped(IBinder token, Bundle icicle,
5466            PersistableBundle persistentState, CharSequence description) {
5467        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5468
5469        // Refuse possible leaked file descriptors
5470        if (icicle != null && icicle.hasFileDescriptors()) {
5471            throw new IllegalArgumentException("File descriptors passed in Bundle");
5472        }
5473
5474        final long origId = Binder.clearCallingIdentity();
5475
5476        synchronized (this) {
5477            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5478            if (r != null) {
5479                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5480            }
5481        }
5482
5483        trimApplications();
5484
5485        Binder.restoreCallingIdentity(origId);
5486    }
5487
5488    @Override
5489    public final void activityDestroyed(IBinder token) {
5490        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5491        synchronized (this) {
5492            ActivityStack stack = ActivityRecord.getStackLocked(token);
5493            if (stack != null) {
5494                stack.activityDestroyedLocked(token);
5495            }
5496        }
5497    }
5498
5499    @Override
5500    public String getCallingPackage(IBinder token) {
5501        synchronized (this) {
5502            ActivityRecord r = getCallingRecordLocked(token);
5503            return r != null ? r.info.packageName : null;
5504        }
5505    }
5506
5507    @Override
5508    public ComponentName getCallingActivity(IBinder token) {
5509        synchronized (this) {
5510            ActivityRecord r = getCallingRecordLocked(token);
5511            return r != null ? r.intent.getComponent() : null;
5512        }
5513    }
5514
5515    private ActivityRecord getCallingRecordLocked(IBinder token) {
5516        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5517        if (r == null) {
5518            return null;
5519        }
5520        return r.resultTo;
5521    }
5522
5523    @Override
5524    public ComponentName getActivityClassForToken(IBinder token) {
5525        synchronized(this) {
5526            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5527            if (r == null) {
5528                return null;
5529            }
5530            return r.intent.getComponent();
5531        }
5532    }
5533
5534    @Override
5535    public String getPackageForToken(IBinder token) {
5536        synchronized(this) {
5537            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5538            if (r == null) {
5539                return null;
5540            }
5541            return r.packageName;
5542        }
5543    }
5544
5545    @Override
5546    public IIntentSender getIntentSender(int type,
5547            String packageName, IBinder token, String resultWho,
5548            int requestCode, Intent[] intents, String[] resolvedTypes,
5549            int flags, Bundle options, int userId) {
5550        enforceNotIsolatedCaller("getIntentSender");
5551        // Refuse possible leaked file descriptors
5552        if (intents != null) {
5553            if (intents.length < 1) {
5554                throw new IllegalArgumentException("Intents array length must be >= 1");
5555            }
5556            for (int i=0; i<intents.length; i++) {
5557                Intent intent = intents[i];
5558                if (intent != null) {
5559                    if (intent.hasFileDescriptors()) {
5560                        throw new IllegalArgumentException("File descriptors passed in Intent");
5561                    }
5562                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5563                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5564                        throw new IllegalArgumentException(
5565                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5566                    }
5567                    intents[i] = new Intent(intent);
5568                }
5569            }
5570            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5571                throw new IllegalArgumentException(
5572                        "Intent array length does not match resolvedTypes length");
5573            }
5574        }
5575        if (options != null) {
5576            if (options.hasFileDescriptors()) {
5577                throw new IllegalArgumentException("File descriptors passed in options");
5578            }
5579        }
5580
5581        synchronized(this) {
5582            int callingUid = Binder.getCallingUid();
5583            int origUserId = userId;
5584            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5585                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5586                    "getIntentSender", null);
5587            if (origUserId == UserHandle.USER_CURRENT) {
5588                // We don't want to evaluate this until the pending intent is
5589                // actually executed.  However, we do want to always do the
5590                // security checking for it above.
5591                userId = UserHandle.USER_CURRENT;
5592            }
5593            try {
5594                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5595                    int uid = AppGlobals.getPackageManager()
5596                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5597                    if (!UserHandle.isSameApp(callingUid, uid)) {
5598                        String msg = "Permission Denial: getIntentSender() from pid="
5599                            + Binder.getCallingPid()
5600                            + ", uid=" + Binder.getCallingUid()
5601                            + ", (need uid=" + uid + ")"
5602                            + " is not allowed to send as package " + packageName;
5603                        Slog.w(TAG, msg);
5604                        throw new SecurityException(msg);
5605                    }
5606                }
5607
5608                return getIntentSenderLocked(type, packageName, callingUid, userId,
5609                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5610
5611            } catch (RemoteException e) {
5612                throw new SecurityException(e);
5613            }
5614        }
5615    }
5616
5617    IIntentSender getIntentSenderLocked(int type, String packageName,
5618            int callingUid, int userId, IBinder token, String resultWho,
5619            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5620            Bundle options) {
5621        if (DEBUG_MU)
5622            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5623        ActivityRecord activity = null;
5624        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5625            activity = ActivityRecord.isInStackLocked(token);
5626            if (activity == null) {
5627                return null;
5628            }
5629            if (activity.finishing) {
5630                return null;
5631            }
5632        }
5633
5634        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5635        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5636        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5637        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5638                |PendingIntent.FLAG_UPDATE_CURRENT);
5639
5640        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5641                type, packageName, activity, resultWho,
5642                requestCode, intents, resolvedTypes, flags, options, userId);
5643        WeakReference<PendingIntentRecord> ref;
5644        ref = mIntentSenderRecords.get(key);
5645        PendingIntentRecord rec = ref != null ? ref.get() : null;
5646        if (rec != null) {
5647            if (!cancelCurrent) {
5648                if (updateCurrent) {
5649                    if (rec.key.requestIntent != null) {
5650                        rec.key.requestIntent.replaceExtras(intents != null ?
5651                                intents[intents.length - 1] : null);
5652                    }
5653                    if (intents != null) {
5654                        intents[intents.length-1] = rec.key.requestIntent;
5655                        rec.key.allIntents = intents;
5656                        rec.key.allResolvedTypes = resolvedTypes;
5657                    } else {
5658                        rec.key.allIntents = null;
5659                        rec.key.allResolvedTypes = null;
5660                    }
5661                }
5662                return rec;
5663            }
5664            rec.canceled = true;
5665            mIntentSenderRecords.remove(key);
5666        }
5667        if (noCreate) {
5668            return rec;
5669        }
5670        rec = new PendingIntentRecord(this, key, callingUid);
5671        mIntentSenderRecords.put(key, rec.ref);
5672        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5673            if (activity.pendingResults == null) {
5674                activity.pendingResults
5675                        = new HashSet<WeakReference<PendingIntentRecord>>();
5676            }
5677            activity.pendingResults.add(rec.ref);
5678        }
5679        return rec;
5680    }
5681
5682    @Override
5683    public void cancelIntentSender(IIntentSender sender) {
5684        if (!(sender instanceof PendingIntentRecord)) {
5685            return;
5686        }
5687        synchronized(this) {
5688            PendingIntentRecord rec = (PendingIntentRecord)sender;
5689            try {
5690                int uid = AppGlobals.getPackageManager()
5691                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5692                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5693                    String msg = "Permission Denial: cancelIntentSender() from pid="
5694                        + Binder.getCallingPid()
5695                        + ", uid=" + Binder.getCallingUid()
5696                        + " is not allowed to cancel packges "
5697                        + rec.key.packageName;
5698                    Slog.w(TAG, msg);
5699                    throw new SecurityException(msg);
5700                }
5701            } catch (RemoteException e) {
5702                throw new SecurityException(e);
5703            }
5704            cancelIntentSenderLocked(rec, true);
5705        }
5706    }
5707
5708    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5709        rec.canceled = true;
5710        mIntentSenderRecords.remove(rec.key);
5711        if (cleanActivity && rec.key.activity != null) {
5712            rec.key.activity.pendingResults.remove(rec.ref);
5713        }
5714    }
5715
5716    @Override
5717    public String getPackageForIntentSender(IIntentSender pendingResult) {
5718        if (!(pendingResult instanceof PendingIntentRecord)) {
5719            return null;
5720        }
5721        try {
5722            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5723            return res.key.packageName;
5724        } catch (ClassCastException e) {
5725        }
5726        return null;
5727    }
5728
5729    @Override
5730    public int getUidForIntentSender(IIntentSender sender) {
5731        if (sender instanceof PendingIntentRecord) {
5732            try {
5733                PendingIntentRecord res = (PendingIntentRecord)sender;
5734                return res.uid;
5735            } catch (ClassCastException e) {
5736            }
5737        }
5738        return -1;
5739    }
5740
5741    @Override
5742    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5743        if (!(pendingResult instanceof PendingIntentRecord)) {
5744            return false;
5745        }
5746        try {
5747            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5748            if (res.key.allIntents == null) {
5749                return false;
5750            }
5751            for (int i=0; i<res.key.allIntents.length; i++) {
5752                Intent intent = res.key.allIntents[i];
5753                if (intent.getPackage() != null && intent.getComponent() != null) {
5754                    return false;
5755                }
5756            }
5757            return true;
5758        } catch (ClassCastException e) {
5759        }
5760        return false;
5761    }
5762
5763    @Override
5764    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5765        if (!(pendingResult instanceof PendingIntentRecord)) {
5766            return false;
5767        }
5768        try {
5769            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5770            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5771                return true;
5772            }
5773            return false;
5774        } catch (ClassCastException e) {
5775        }
5776        return false;
5777    }
5778
5779    @Override
5780    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5781        if (!(pendingResult instanceof PendingIntentRecord)) {
5782            return null;
5783        }
5784        try {
5785            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5786            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5787        } catch (ClassCastException e) {
5788        }
5789        return null;
5790    }
5791
5792    @Override
5793    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5794        if (!(pendingResult instanceof PendingIntentRecord)) {
5795            return null;
5796        }
5797        try {
5798            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5799            Intent intent = res.key.requestIntent;
5800            if (intent != null) {
5801                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5802                        || res.lastTagPrefix.equals(prefix))) {
5803                    return res.lastTag;
5804                }
5805                res.lastTagPrefix = prefix;
5806                StringBuilder sb = new StringBuilder(128);
5807                if (prefix != null) {
5808                    sb.append(prefix);
5809                }
5810                if (intent.getAction() != null) {
5811                    sb.append(intent.getAction());
5812                } else if (intent.getComponent() != null) {
5813                    intent.getComponent().appendShortString(sb);
5814                } else {
5815                    sb.append("?");
5816                }
5817                return res.lastTag = sb.toString();
5818            }
5819        } catch (ClassCastException e) {
5820        }
5821        return null;
5822    }
5823
5824    @Override
5825    public void setProcessLimit(int max) {
5826        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5827                "setProcessLimit()");
5828        synchronized (this) {
5829            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5830            mProcessLimitOverride = max;
5831        }
5832        trimApplications();
5833    }
5834
5835    @Override
5836    public int getProcessLimit() {
5837        synchronized (this) {
5838            return mProcessLimitOverride;
5839        }
5840    }
5841
5842    void foregroundTokenDied(ForegroundToken token) {
5843        synchronized (ActivityManagerService.this) {
5844            synchronized (mPidsSelfLocked) {
5845                ForegroundToken cur
5846                    = mForegroundProcesses.get(token.pid);
5847                if (cur != token) {
5848                    return;
5849                }
5850                mForegroundProcesses.remove(token.pid);
5851                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5852                if (pr == null) {
5853                    return;
5854                }
5855                pr.forcingToForeground = null;
5856                updateProcessForegroundLocked(pr, false, false);
5857            }
5858            updateOomAdjLocked();
5859        }
5860    }
5861
5862    @Override
5863    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5864        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5865                "setProcessForeground()");
5866        synchronized(this) {
5867            boolean changed = false;
5868
5869            synchronized (mPidsSelfLocked) {
5870                ProcessRecord pr = mPidsSelfLocked.get(pid);
5871                if (pr == null && isForeground) {
5872                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5873                    return;
5874                }
5875                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5876                if (oldToken != null) {
5877                    oldToken.token.unlinkToDeath(oldToken, 0);
5878                    mForegroundProcesses.remove(pid);
5879                    if (pr != null) {
5880                        pr.forcingToForeground = null;
5881                    }
5882                    changed = true;
5883                }
5884                if (isForeground && token != null) {
5885                    ForegroundToken newToken = new ForegroundToken() {
5886                        @Override
5887                        public void binderDied() {
5888                            foregroundTokenDied(this);
5889                        }
5890                    };
5891                    newToken.pid = pid;
5892                    newToken.token = token;
5893                    try {
5894                        token.linkToDeath(newToken, 0);
5895                        mForegroundProcesses.put(pid, newToken);
5896                        pr.forcingToForeground = token;
5897                        changed = true;
5898                    } catch (RemoteException e) {
5899                        // If the process died while doing this, we will later
5900                        // do the cleanup with the process death link.
5901                    }
5902                }
5903            }
5904
5905            if (changed) {
5906                updateOomAdjLocked();
5907            }
5908        }
5909    }
5910
5911    // =========================================================
5912    // PERMISSIONS
5913    // =========================================================
5914
5915    static class PermissionController extends IPermissionController.Stub {
5916        ActivityManagerService mActivityManagerService;
5917        PermissionController(ActivityManagerService activityManagerService) {
5918            mActivityManagerService = activityManagerService;
5919        }
5920
5921        @Override
5922        public boolean checkPermission(String permission, int pid, int uid) {
5923            return mActivityManagerService.checkPermission(permission, pid,
5924                    uid) == PackageManager.PERMISSION_GRANTED;
5925        }
5926    }
5927
5928    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5929        @Override
5930        public int checkComponentPermission(String permission, int pid, int uid,
5931                int owningUid, boolean exported) {
5932            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5933                    owningUid, exported);
5934        }
5935
5936        @Override
5937        public Object getAMSLock() {
5938            return ActivityManagerService.this;
5939        }
5940    }
5941
5942    /**
5943     * This can be called with or without the global lock held.
5944     */
5945    int checkComponentPermission(String permission, int pid, int uid,
5946            int owningUid, boolean exported) {
5947        // We might be performing an operation on behalf of an indirect binder
5948        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5949        // client identity accordingly before proceeding.
5950        Identity tlsIdentity = sCallerIdentity.get();
5951        if (tlsIdentity != null) {
5952            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5953                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5954            uid = tlsIdentity.uid;
5955            pid = tlsIdentity.pid;
5956        }
5957
5958        if (pid == MY_PID) {
5959            return PackageManager.PERMISSION_GRANTED;
5960        }
5961
5962        return ActivityManager.checkComponentPermission(permission, uid,
5963                owningUid, exported);
5964    }
5965
5966    /**
5967     * As the only public entry point for permissions checking, this method
5968     * can enforce the semantic that requesting a check on a null global
5969     * permission is automatically denied.  (Internally a null permission
5970     * string is used when calling {@link #checkComponentPermission} in cases
5971     * when only uid-based security is needed.)
5972     *
5973     * This can be called with or without the global lock held.
5974     */
5975    @Override
5976    public int checkPermission(String permission, int pid, int uid) {
5977        if (permission == null) {
5978            return PackageManager.PERMISSION_DENIED;
5979        }
5980        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5981    }
5982
5983    /**
5984     * Binder IPC calls go through the public entry point.
5985     * This can be called with or without the global lock held.
5986     */
5987    int checkCallingPermission(String permission) {
5988        return checkPermission(permission,
5989                Binder.getCallingPid(),
5990                UserHandle.getAppId(Binder.getCallingUid()));
5991    }
5992
5993    /**
5994     * This can be called with or without the global lock held.
5995     */
5996    void enforceCallingPermission(String permission, String func) {
5997        if (checkCallingPermission(permission)
5998                == PackageManager.PERMISSION_GRANTED) {
5999            return;
6000        }
6001
6002        String msg = "Permission Denial: " + func + " from pid="
6003                + Binder.getCallingPid()
6004                + ", uid=" + Binder.getCallingUid()
6005                + " requires " + permission;
6006        Slog.w(TAG, msg);
6007        throw new SecurityException(msg);
6008    }
6009
6010    /**
6011     * Determine if UID is holding permissions required to access {@link Uri} in
6012     * the given {@link ProviderInfo}. Final permission checking is always done
6013     * in {@link ContentProvider}.
6014     */
6015    private final boolean checkHoldingPermissionsLocked(
6016            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6017        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6018                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6019
6020        if (pi.applicationInfo.uid == uid) {
6021            return true;
6022        } else if (!pi.exported) {
6023            return false;
6024        }
6025
6026        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6027        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6028        try {
6029            // check if target holds top-level <provider> permissions
6030            if (!readMet && pi.readPermission != null
6031                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6032                readMet = true;
6033            }
6034            if (!writeMet && pi.writePermission != null
6035                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6036                writeMet = true;
6037            }
6038
6039            // track if unprotected read/write is allowed; any denied
6040            // <path-permission> below removes this ability
6041            boolean allowDefaultRead = pi.readPermission == null;
6042            boolean allowDefaultWrite = pi.writePermission == null;
6043
6044            // check if target holds any <path-permission> that match uri
6045            final PathPermission[] pps = pi.pathPermissions;
6046            if (pps != null) {
6047                final String path = grantUri.uri.getPath();
6048                int i = pps.length;
6049                while (i > 0 && (!readMet || !writeMet)) {
6050                    i--;
6051                    PathPermission pp = pps[i];
6052                    if (pp.match(path)) {
6053                        if (!readMet) {
6054                            final String pprperm = pp.getReadPermission();
6055                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6056                                    + pprperm + " for " + pp.getPath()
6057                                    + ": match=" + pp.match(path)
6058                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6059                            if (pprperm != null) {
6060                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6061                                    readMet = true;
6062                                } else {
6063                                    allowDefaultRead = false;
6064                                }
6065                            }
6066                        }
6067                        if (!writeMet) {
6068                            final String ppwperm = pp.getWritePermission();
6069                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6070                                    + ppwperm + " for " + pp.getPath()
6071                                    + ": match=" + pp.match(path)
6072                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6073                            if (ppwperm != null) {
6074                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6075                                    writeMet = true;
6076                                } else {
6077                                    allowDefaultWrite = false;
6078                                }
6079                            }
6080                        }
6081                    }
6082                }
6083            }
6084
6085            // grant unprotected <provider> read/write, if not blocked by
6086            // <path-permission> above
6087            if (allowDefaultRead) readMet = true;
6088            if (allowDefaultWrite) writeMet = true;
6089
6090        } catch (RemoteException e) {
6091            return false;
6092        }
6093
6094        return readMet && writeMet;
6095    }
6096
6097    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6098        ProviderInfo pi = null;
6099        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6100        if (cpr != null) {
6101            pi = cpr.info;
6102        } else {
6103            try {
6104                pi = AppGlobals.getPackageManager().resolveContentProvider(
6105                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6106            } catch (RemoteException ex) {
6107            }
6108        }
6109        return pi;
6110    }
6111
6112    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6113        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6114        if (targetUris != null) {
6115            return targetUris.get(grantUri);
6116        }
6117        return null;
6118    }
6119
6120    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6121            String targetPkg, int targetUid, GrantUri grantUri) {
6122        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6123        if (targetUris == null) {
6124            targetUris = Maps.newArrayMap();
6125            mGrantedUriPermissions.put(targetUid, targetUris);
6126        }
6127
6128        UriPermission perm = targetUris.get(grantUri);
6129        if (perm == null) {
6130            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6131            targetUris.put(grantUri, perm);
6132        }
6133
6134        return perm;
6135    }
6136
6137    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6138            final int modeFlags) {
6139        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6140        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6141                : UriPermission.STRENGTH_OWNED;
6142
6143        // Root gets to do everything.
6144        if (uid == 0) {
6145            return true;
6146        }
6147
6148        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6149        if (perms == null) return false;
6150
6151        // First look for exact match
6152        final UriPermission exactPerm = perms.get(grantUri);
6153        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6154            return true;
6155        }
6156
6157        // No exact match, look for prefixes
6158        final int N = perms.size();
6159        for (int i = 0; i < N; i++) {
6160            final UriPermission perm = perms.valueAt(i);
6161            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6162                    && perm.getStrength(modeFlags) >= minStrength) {
6163                return true;
6164            }
6165        }
6166
6167        return false;
6168    }
6169
6170    @Override
6171    public int checkUriPermission(Uri uri, int pid, int uid,
6172            final int modeFlags, int userId) {
6173        enforceNotIsolatedCaller("checkUriPermission");
6174
6175        // Another redirected-binder-call permissions check as in
6176        // {@link checkComponentPermission}.
6177        Identity tlsIdentity = sCallerIdentity.get();
6178        if (tlsIdentity != null) {
6179            uid = tlsIdentity.uid;
6180            pid = tlsIdentity.pid;
6181        }
6182
6183        // Our own process gets to do everything.
6184        if (pid == MY_PID) {
6185            return PackageManager.PERMISSION_GRANTED;
6186        }
6187        synchronized (this) {
6188            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6189                    ? PackageManager.PERMISSION_GRANTED
6190                    : PackageManager.PERMISSION_DENIED;
6191        }
6192    }
6193
6194    /**
6195     * Check if the targetPkg can be granted permission to access uri by
6196     * the callingUid using the given modeFlags.  Throws a security exception
6197     * if callingUid is not allowed to do this.  Returns the uid of the target
6198     * if the URI permission grant should be performed; returns -1 if it is not
6199     * needed (for example targetPkg already has permission to access the URI).
6200     * If you already know the uid of the target, you can supply it in
6201     * lastTargetUid else set that to -1.
6202     */
6203    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6204            final int modeFlags, int lastTargetUid) {
6205        if (!Intent.isAccessUriMode(modeFlags)) {
6206            return -1;
6207        }
6208
6209        if (targetPkg != null) {
6210            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6211                    "Checking grant " + targetPkg + " permission to " + grantUri);
6212        }
6213
6214        final IPackageManager pm = AppGlobals.getPackageManager();
6215
6216        // If this is not a content: uri, we can't do anything with it.
6217        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6218            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6219                    "Can't grant URI permission for non-content URI: " + grantUri);
6220            return -1;
6221        }
6222
6223        final String authority = grantUri.uri.getAuthority();
6224        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6225        if (pi == null) {
6226            Slog.w(TAG, "No content provider found for permission check: " +
6227                    grantUri.uri.toSafeString());
6228            return -1;
6229        }
6230
6231        int targetUid = lastTargetUid;
6232        if (targetUid < 0 && targetPkg != null) {
6233            try {
6234                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6235                if (targetUid < 0) {
6236                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6237                            "Can't grant URI permission no uid for: " + targetPkg);
6238                    return -1;
6239                }
6240            } catch (RemoteException ex) {
6241                return -1;
6242            }
6243        }
6244
6245        if (targetUid >= 0) {
6246            // First...  does the target actually need this permission?
6247            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6248                // No need to grant the target this permission.
6249                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6250                        "Target " + targetPkg + " already has full permission to " + grantUri);
6251                return -1;
6252            }
6253        } else {
6254            // First...  there is no target package, so can anyone access it?
6255            boolean allowed = pi.exported;
6256            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6257                if (pi.readPermission != null) {
6258                    allowed = false;
6259                }
6260            }
6261            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6262                if (pi.writePermission != null) {
6263                    allowed = false;
6264                }
6265            }
6266            if (allowed) {
6267                return -1;
6268            }
6269        }
6270
6271        // Second...  is the provider allowing granting of URI permissions?
6272        if (!pi.grantUriPermissions) {
6273            throw new SecurityException("Provider " + pi.packageName
6274                    + "/" + pi.name
6275                    + " does not allow granting of Uri permissions (uri "
6276                    + grantUri + ")");
6277        }
6278        if (pi.uriPermissionPatterns != null) {
6279            final int N = pi.uriPermissionPatterns.length;
6280            boolean allowed = false;
6281            for (int i=0; i<N; i++) {
6282                if (pi.uriPermissionPatterns[i] != null
6283                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6284                    allowed = true;
6285                    break;
6286                }
6287            }
6288            if (!allowed) {
6289                throw new SecurityException("Provider " + pi.packageName
6290                        + "/" + pi.name
6291                        + " does not allow granting of permission to path of Uri "
6292                        + grantUri);
6293            }
6294        }
6295
6296        // Third...  does the caller itself have permission to access
6297        // this uri?
6298        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6299            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6300                // Require they hold a strong enough Uri permission
6301                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6302                    throw new SecurityException("Uid " + callingUid
6303                            + " does not have permission to uri " + grantUri);
6304                }
6305            }
6306        }
6307        return targetUid;
6308    }
6309
6310    @Override
6311    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6312            final int modeFlags, int userId) {
6313        enforceNotIsolatedCaller("checkGrantUriPermission");
6314        synchronized(this) {
6315            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6316                    new GrantUri(userId, uri, false), modeFlags, -1);
6317        }
6318    }
6319
6320    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6321            final int modeFlags, UriPermissionOwner owner) {
6322        if (!Intent.isAccessUriMode(modeFlags)) {
6323            return;
6324        }
6325
6326        // So here we are: the caller has the assumed permission
6327        // to the uri, and the target doesn't.  Let's now give this to
6328        // the target.
6329
6330        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6331                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6332
6333        final String authority = grantUri.uri.getAuthority();
6334        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6335        if (pi == null) {
6336            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6337            return;
6338        }
6339
6340        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6341            grantUri.prefix = true;
6342        }
6343        final UriPermission perm = findOrCreateUriPermissionLocked(
6344                pi.packageName, targetPkg, targetUid, grantUri);
6345        perm.grantModes(modeFlags, owner);
6346    }
6347
6348    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6349            final int modeFlags, UriPermissionOwner owner) {
6350        if (targetPkg == null) {
6351            throw new NullPointerException("targetPkg");
6352        }
6353
6354        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6355                -1);
6356        if (targetUid < 0) {
6357            return;
6358        }
6359
6360        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6361                owner);
6362    }
6363
6364    static class NeededUriGrants extends ArrayList<GrantUri> {
6365        final String targetPkg;
6366        final int targetUid;
6367        final int flags;
6368
6369        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6370            this.targetPkg = targetPkg;
6371            this.targetUid = targetUid;
6372            this.flags = flags;
6373        }
6374    }
6375
6376    /**
6377     * Like checkGrantUriPermissionLocked, but takes an Intent.
6378     */
6379    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6380            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6381        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6382                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6383                + " clip=" + (intent != null ? intent.getClipData() : null)
6384                + " from " + intent + "; flags=0x"
6385                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6386
6387        if (targetPkg == null) {
6388            throw new NullPointerException("targetPkg");
6389        }
6390
6391        if (intent == null) {
6392            return null;
6393        }
6394        Uri data = intent.getData();
6395        ClipData clip = intent.getClipData();
6396        if (data == null && clip == null) {
6397            return null;
6398        }
6399
6400        if (data != null) {
6401            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6402            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6403                    needed != null ? needed.targetUid : -1);
6404            if (targetUid > 0) {
6405                if (needed == null) {
6406                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6407                }
6408                needed.add(grantUri);
6409            }
6410        }
6411        if (clip != null) {
6412            for (int i=0; i<clip.getItemCount(); i++) {
6413                Uri uri = clip.getItemAt(i).getUri();
6414                if (uri != null) {
6415                    int targetUid = -1;
6416                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6417                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6418                            needed != null ? needed.targetUid : -1);
6419                    if (targetUid > 0) {
6420                        if (needed == null) {
6421                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6422                        }
6423                        needed.add(grantUri);
6424                    }
6425                } else {
6426                    Intent clipIntent = clip.getItemAt(i).getIntent();
6427                    if (clipIntent != null) {
6428                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6429                                callingUid, targetPkg, clipIntent, mode, needed);
6430                        if (newNeeded != null) {
6431                            needed = newNeeded;
6432                        }
6433                    }
6434                }
6435            }
6436        }
6437
6438        return needed;
6439    }
6440
6441    /**
6442     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6443     */
6444    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6445            UriPermissionOwner owner) {
6446        if (needed != null) {
6447            for (int i=0; i<needed.size(); i++) {
6448                GrantUri grantUri = needed.get(i);
6449                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6450                        grantUri, needed.flags, owner);
6451            }
6452        }
6453    }
6454
6455    void grantUriPermissionFromIntentLocked(int callingUid,
6456            String targetPkg, Intent intent, UriPermissionOwner owner) {
6457        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6458                intent, intent != null ? intent.getFlags() : 0, null);
6459        if (needed == null) {
6460            return;
6461        }
6462
6463        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6464    }
6465
6466    @Override
6467    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6468            final int modeFlags, int userId) {
6469        enforceNotIsolatedCaller("grantUriPermission");
6470        GrantUri grantUri = new GrantUri(userId, uri, false);
6471        synchronized(this) {
6472            final ProcessRecord r = getRecordForAppLocked(caller);
6473            if (r == null) {
6474                throw new SecurityException("Unable to find app for caller "
6475                        + caller
6476                        + " when granting permission to uri " + grantUri);
6477            }
6478            if (targetPkg == null) {
6479                throw new IllegalArgumentException("null target");
6480            }
6481            if (grantUri == null) {
6482                throw new IllegalArgumentException("null uri");
6483            }
6484
6485            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6486                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6487                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6488                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6489
6490            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6491        }
6492    }
6493
6494    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6495        if (perm.modeFlags == 0) {
6496            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6497                    perm.targetUid);
6498            if (perms != null) {
6499                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6500                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6501
6502                perms.remove(perm.uri);
6503                if (perms.isEmpty()) {
6504                    mGrantedUriPermissions.remove(perm.targetUid);
6505                }
6506            }
6507        }
6508    }
6509
6510    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6511        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6512
6513        final IPackageManager pm = AppGlobals.getPackageManager();
6514        final String authority = grantUri.uri.getAuthority();
6515        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6516        if (pi == null) {
6517            Slog.w(TAG, "No content provider found for permission revoke: "
6518                    + grantUri.toSafeString());
6519            return;
6520        }
6521
6522        // Does the caller have this permission on the URI?
6523        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6524            // Right now, if you are not the original owner of the permission,
6525            // you are not allowed to revoke it.
6526            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6527                throw new SecurityException("Uid " + callingUid
6528                        + " does not have permission to uri " + grantUri);
6529            //}
6530        }
6531
6532        boolean persistChanged = false;
6533
6534        // Go through all of the permissions and remove any that match.
6535        int N = mGrantedUriPermissions.size();
6536        for (int i = 0; i < N; i++) {
6537            final int targetUid = mGrantedUriPermissions.keyAt(i);
6538            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6539
6540            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6541                final UriPermission perm = it.next();
6542                if (perm.uri.sourceUserId == grantUri.sourceUserId
6543                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6544                    if (DEBUG_URI_PERMISSION)
6545                        Slog.v(TAG,
6546                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6547                    persistChanged |= perm.revokeModes(
6548                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6549                    if (perm.modeFlags == 0) {
6550                        it.remove();
6551                    }
6552                }
6553            }
6554
6555            if (perms.isEmpty()) {
6556                mGrantedUriPermissions.remove(targetUid);
6557                N--;
6558                i--;
6559            }
6560        }
6561
6562        if (persistChanged) {
6563            schedulePersistUriGrants();
6564        }
6565    }
6566
6567    @Override
6568    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6569            int userId) {
6570        enforceNotIsolatedCaller("revokeUriPermission");
6571        synchronized(this) {
6572            final ProcessRecord r = getRecordForAppLocked(caller);
6573            if (r == null) {
6574                throw new SecurityException("Unable to find app for caller "
6575                        + caller
6576                        + " when revoking permission to uri " + uri);
6577            }
6578            if (uri == null) {
6579                Slog.w(TAG, "revokeUriPermission: null uri");
6580                return;
6581            }
6582
6583            if (!Intent.isAccessUriMode(modeFlags)) {
6584                return;
6585            }
6586
6587            final IPackageManager pm = AppGlobals.getPackageManager();
6588            final String authority = uri.getAuthority();
6589            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6590            if (pi == null) {
6591                Slog.w(TAG, "No content provider found for permission revoke: "
6592                        + uri.toSafeString());
6593                return;
6594            }
6595
6596            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6597        }
6598    }
6599
6600    /**
6601     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6602     * given package.
6603     *
6604     * @param packageName Package name to match, or {@code null} to apply to all
6605     *            packages.
6606     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6607     *            to all users.
6608     * @param persistable If persistable grants should be removed.
6609     */
6610    private void removeUriPermissionsForPackageLocked(
6611            String packageName, int userHandle, boolean persistable) {
6612        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6613            throw new IllegalArgumentException("Must narrow by either package or user");
6614        }
6615
6616        boolean persistChanged = false;
6617
6618        int N = mGrantedUriPermissions.size();
6619        for (int i = 0; i < N; i++) {
6620            final int targetUid = mGrantedUriPermissions.keyAt(i);
6621            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6622
6623            // Only inspect grants matching user
6624            if (userHandle == UserHandle.USER_ALL
6625                    || userHandle == UserHandle.getUserId(targetUid)) {
6626                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6627                    final UriPermission perm = it.next();
6628
6629                    // Only inspect grants matching package
6630                    if (packageName == null || perm.sourcePkg.equals(packageName)
6631                            || perm.targetPkg.equals(packageName)) {
6632                        persistChanged |= perm.revokeModes(
6633                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6634
6635                        // Only remove when no modes remain; any persisted grants
6636                        // will keep this alive.
6637                        if (perm.modeFlags == 0) {
6638                            it.remove();
6639                        }
6640                    }
6641                }
6642
6643                if (perms.isEmpty()) {
6644                    mGrantedUriPermissions.remove(targetUid);
6645                    N--;
6646                    i--;
6647                }
6648            }
6649        }
6650
6651        if (persistChanged) {
6652            schedulePersistUriGrants();
6653        }
6654    }
6655
6656    @Override
6657    public IBinder newUriPermissionOwner(String name) {
6658        enforceNotIsolatedCaller("newUriPermissionOwner");
6659        synchronized(this) {
6660            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6661            return owner.getExternalTokenLocked();
6662        }
6663    }
6664
6665    @Override
6666    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6667            final int modeFlags, int userId) {
6668        synchronized(this) {
6669            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6670            if (owner == null) {
6671                throw new IllegalArgumentException("Unknown owner: " + token);
6672            }
6673            if (fromUid != Binder.getCallingUid()) {
6674                if (Binder.getCallingUid() != Process.myUid()) {
6675                    // Only system code can grant URI permissions on behalf
6676                    // of other users.
6677                    throw new SecurityException("nice try");
6678                }
6679            }
6680            if (targetPkg == null) {
6681                throw new IllegalArgumentException("null target");
6682            }
6683            if (uri == null) {
6684                throw new IllegalArgumentException("null uri");
6685            }
6686
6687            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6688                    modeFlags, owner);
6689        }
6690    }
6691
6692    @Override
6693    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6694        synchronized(this) {
6695            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6696            if (owner == null) {
6697                throw new IllegalArgumentException("Unknown owner: " + token);
6698            }
6699
6700            if (uri == null) {
6701                owner.removeUriPermissionsLocked(mode);
6702            } else {
6703                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6704            }
6705        }
6706    }
6707
6708    private void schedulePersistUriGrants() {
6709        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6710            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6711                    10 * DateUtils.SECOND_IN_MILLIS);
6712        }
6713    }
6714
6715    private void writeGrantedUriPermissions() {
6716        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6717
6718        // Snapshot permissions so we can persist without lock
6719        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6720        synchronized (this) {
6721            final int size = mGrantedUriPermissions.size();
6722            for (int i = 0; i < size; i++) {
6723                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6724                for (UriPermission perm : perms.values()) {
6725                    if (perm.persistedModeFlags != 0) {
6726                        persist.add(perm.snapshot());
6727                    }
6728                }
6729            }
6730        }
6731
6732        FileOutputStream fos = null;
6733        try {
6734            fos = mGrantFile.startWrite();
6735
6736            XmlSerializer out = new FastXmlSerializer();
6737            out.setOutput(fos, "utf-8");
6738            out.startDocument(null, true);
6739            out.startTag(null, TAG_URI_GRANTS);
6740            for (UriPermission.Snapshot perm : persist) {
6741                out.startTag(null, TAG_URI_GRANT);
6742                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6743                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6744                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6745                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6746                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6747                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6748                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6749                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6750                out.endTag(null, TAG_URI_GRANT);
6751            }
6752            out.endTag(null, TAG_URI_GRANTS);
6753            out.endDocument();
6754
6755            mGrantFile.finishWrite(fos);
6756        } catch (IOException e) {
6757            if (fos != null) {
6758                mGrantFile.failWrite(fos);
6759            }
6760        }
6761    }
6762
6763    private void readGrantedUriPermissionsLocked() {
6764        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6765
6766        final long now = System.currentTimeMillis();
6767
6768        FileInputStream fis = null;
6769        try {
6770            fis = mGrantFile.openRead();
6771            final XmlPullParser in = Xml.newPullParser();
6772            in.setInput(fis, null);
6773
6774            int type;
6775            while ((type = in.next()) != END_DOCUMENT) {
6776                final String tag = in.getName();
6777                if (type == START_TAG) {
6778                    if (TAG_URI_GRANT.equals(tag)) {
6779                        final int sourceUserId;
6780                        final int targetUserId;
6781                        final int userHandle = readIntAttribute(in,
6782                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6783                        if (userHandle != UserHandle.USER_NULL) {
6784                            // For backwards compatibility.
6785                            sourceUserId = userHandle;
6786                            targetUserId = userHandle;
6787                        } else {
6788                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6789                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6790                        }
6791                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6792                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6793                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6794                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6795                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6796                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6797
6798                        // Sanity check that provider still belongs to source package
6799                        final ProviderInfo pi = getProviderInfoLocked(
6800                                uri.getAuthority(), sourceUserId);
6801                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6802                            int targetUid = -1;
6803                            try {
6804                                targetUid = AppGlobals.getPackageManager()
6805                                        .getPackageUid(targetPkg, targetUserId);
6806                            } catch (RemoteException e) {
6807                            }
6808                            if (targetUid != -1) {
6809                                final UriPermission perm = findOrCreateUriPermissionLocked(
6810                                        sourcePkg, targetPkg, targetUid,
6811                                        new GrantUri(sourceUserId, uri, prefix));
6812                                perm.initPersistedModes(modeFlags, createdTime);
6813                            }
6814                        } else {
6815                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6816                                    + " but instead found " + pi);
6817                        }
6818                    }
6819                }
6820            }
6821        } catch (FileNotFoundException e) {
6822            // Missing grants is okay
6823        } catch (IOException e) {
6824            Log.wtf(TAG, "Failed reading Uri grants", e);
6825        } catch (XmlPullParserException e) {
6826            Log.wtf(TAG, "Failed reading Uri grants", e);
6827        } finally {
6828            IoUtils.closeQuietly(fis);
6829        }
6830    }
6831
6832    @Override
6833    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6834        enforceNotIsolatedCaller("takePersistableUriPermission");
6835
6836        Preconditions.checkFlagsArgument(modeFlags,
6837                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6838
6839        synchronized (this) {
6840            final int callingUid = Binder.getCallingUid();
6841            boolean persistChanged = false;
6842            GrantUri grantUri = new GrantUri(userId, uri, false);
6843
6844            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6845                    new GrantUri(userId, uri, false));
6846            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6847                    new GrantUri(userId, uri, true));
6848
6849            final boolean exactValid = (exactPerm != null)
6850                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6851            final boolean prefixValid = (prefixPerm != null)
6852                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6853
6854            if (!(exactValid || prefixValid)) {
6855                throw new SecurityException("No persistable permission grants found for UID "
6856                        + callingUid + " and Uri " + grantUri.toSafeString());
6857            }
6858
6859            if (exactValid) {
6860                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6861            }
6862            if (prefixValid) {
6863                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6864            }
6865
6866            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6867
6868            if (persistChanged) {
6869                schedulePersistUriGrants();
6870            }
6871        }
6872    }
6873
6874    @Override
6875    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6876        enforceNotIsolatedCaller("releasePersistableUriPermission");
6877
6878        Preconditions.checkFlagsArgument(modeFlags,
6879                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6880
6881        synchronized (this) {
6882            final int callingUid = Binder.getCallingUid();
6883            boolean persistChanged = false;
6884
6885            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6886                    new GrantUri(userId, uri, false));
6887            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6888                    new GrantUri(userId, uri, true));
6889            if (exactPerm == null && prefixPerm == null) {
6890                throw new SecurityException("No permission grants found for UID " + callingUid
6891                        + " and Uri " + uri.toSafeString());
6892            }
6893
6894            if (exactPerm != null) {
6895                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6896                removeUriPermissionIfNeededLocked(exactPerm);
6897            }
6898            if (prefixPerm != null) {
6899                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6900                removeUriPermissionIfNeededLocked(prefixPerm);
6901            }
6902
6903            if (persistChanged) {
6904                schedulePersistUriGrants();
6905            }
6906        }
6907    }
6908
6909    /**
6910     * Prune any older {@link UriPermission} for the given UID until outstanding
6911     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6912     *
6913     * @return if any mutations occured that require persisting.
6914     */
6915    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6916        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6917        if (perms == null) return false;
6918        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6919
6920        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6921        for (UriPermission perm : perms.values()) {
6922            if (perm.persistedModeFlags != 0) {
6923                persisted.add(perm);
6924            }
6925        }
6926
6927        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6928        if (trimCount <= 0) return false;
6929
6930        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6931        for (int i = 0; i < trimCount; i++) {
6932            final UriPermission perm = persisted.get(i);
6933
6934            if (DEBUG_URI_PERMISSION) {
6935                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6936            }
6937
6938            perm.releasePersistableModes(~0);
6939            removeUriPermissionIfNeededLocked(perm);
6940        }
6941
6942        return true;
6943    }
6944
6945    @Override
6946    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6947            String packageName, boolean incoming) {
6948        enforceNotIsolatedCaller("getPersistedUriPermissions");
6949        Preconditions.checkNotNull(packageName, "packageName");
6950
6951        final int callingUid = Binder.getCallingUid();
6952        final IPackageManager pm = AppGlobals.getPackageManager();
6953        try {
6954            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6955            if (packageUid != callingUid) {
6956                throw new SecurityException(
6957                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6958            }
6959        } catch (RemoteException e) {
6960            throw new SecurityException("Failed to verify package name ownership");
6961        }
6962
6963        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6964        synchronized (this) {
6965            if (incoming) {
6966                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6967                        callingUid);
6968                if (perms == null) {
6969                    Slog.w(TAG, "No permission grants found for " + packageName);
6970                } else {
6971                    for (UriPermission perm : perms.values()) {
6972                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6973                            result.add(perm.buildPersistedPublicApiObject());
6974                        }
6975                    }
6976                }
6977            } else {
6978                final int size = mGrantedUriPermissions.size();
6979                for (int i = 0; i < size; i++) {
6980                    final ArrayMap<GrantUri, UriPermission> perms =
6981                            mGrantedUriPermissions.valueAt(i);
6982                    for (UriPermission perm : perms.values()) {
6983                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6984                            result.add(perm.buildPersistedPublicApiObject());
6985                        }
6986                    }
6987                }
6988            }
6989        }
6990        return new ParceledListSlice<android.content.UriPermission>(result);
6991    }
6992
6993    @Override
6994    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6995        synchronized (this) {
6996            ProcessRecord app =
6997                who != null ? getRecordForAppLocked(who) : null;
6998            if (app == null) return;
6999
7000            Message msg = Message.obtain();
7001            msg.what = WAIT_FOR_DEBUGGER_MSG;
7002            msg.obj = app;
7003            msg.arg1 = waiting ? 1 : 0;
7004            mHandler.sendMessage(msg);
7005        }
7006    }
7007
7008    @Override
7009    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7010        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7011        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7012        outInfo.availMem = Process.getFreeMemory();
7013        outInfo.totalMem = Process.getTotalMemory();
7014        outInfo.threshold = homeAppMem;
7015        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7016        outInfo.hiddenAppThreshold = cachedAppMem;
7017        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7018                ProcessList.SERVICE_ADJ);
7019        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7020                ProcessList.VISIBLE_APP_ADJ);
7021        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7022                ProcessList.FOREGROUND_APP_ADJ);
7023    }
7024
7025    // =========================================================
7026    // TASK MANAGEMENT
7027    // =========================================================
7028
7029    @Override
7030    public List<IAppTask> getAppTasks() {
7031        int callingUid = Binder.getCallingUid();
7032        long ident = Binder.clearCallingIdentity();
7033        synchronized(this) {
7034            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7035            try {
7036                if (localLOGV) Slog.v(TAG, "getAppTasks");
7037
7038                final int N = mRecentTasks.size();
7039                for (int i = 0; i < N; i++) {
7040                    TaskRecord tr = mRecentTasks.get(i);
7041                    // Skip tasks that are not created by the caller
7042                    if (tr.creatorUid == callingUid) {
7043                        ActivityManager.RecentTaskInfo taskInfo =
7044                                createRecentTaskInfoFromTaskRecord(tr);
7045                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7046                        list.add(taskImpl);
7047                    }
7048                }
7049            } finally {
7050                Binder.restoreCallingIdentity(ident);
7051            }
7052            return list;
7053        }
7054    }
7055
7056    @Override
7057    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7058        final int callingUid = Binder.getCallingUid();
7059        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7060
7061        synchronized(this) {
7062            if (localLOGV) Slog.v(
7063                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7064
7065            final boolean allowed = checkCallingPermission(
7066                    android.Manifest.permission.GET_TASKS)
7067                    == PackageManager.PERMISSION_GRANTED;
7068            if (!allowed) {
7069                Slog.w(TAG, "getTasks: caller " + callingUid
7070                        + " does not hold GET_TASKS; limiting output");
7071            }
7072
7073            // TODO: Improve with MRU list from all ActivityStacks.
7074            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7075        }
7076
7077        return list;
7078    }
7079
7080    TaskRecord getMostRecentTask() {
7081        return mRecentTasks.get(0);
7082    }
7083
7084    /**
7085     * Creates a new RecentTaskInfo from a TaskRecord.
7086     */
7087    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7088        ActivityManager.RecentTaskInfo rti
7089                = new ActivityManager.RecentTaskInfo();
7090        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7091        rti.persistentId = tr.taskId;
7092        rti.baseIntent = new Intent(tr.getBaseIntent());
7093        rti.origActivity = tr.origActivity;
7094        rti.description = tr.lastDescription;
7095        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7096        rti.userId = tr.userId;
7097        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7098        return rti;
7099    }
7100
7101    @Override
7102    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7103            int flags, int userId) {
7104        final int callingUid = Binder.getCallingUid();
7105        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7106                false, true, "getRecentTasks", null);
7107
7108        synchronized (this) {
7109            final boolean allowed = checkCallingPermission(
7110                    android.Manifest.permission.GET_TASKS)
7111                    == PackageManager.PERMISSION_GRANTED;
7112            if (!allowed) {
7113                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7114                        + " does not hold GET_TASKS; limiting output");
7115            }
7116            final boolean detailed = checkCallingPermission(
7117                    android.Manifest.permission.GET_DETAILED_TASKS)
7118                    == PackageManager.PERMISSION_GRANTED;
7119
7120            IPackageManager pm = AppGlobals.getPackageManager();
7121
7122            final int N = mRecentTasks.size();
7123            ArrayList<ActivityManager.RecentTaskInfo> res
7124                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7125                            maxNum < N ? maxNum : N);
7126
7127            final Set<Integer> includedUsers;
7128            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7129                includedUsers = getProfileIdsLocked(userId);
7130            } else {
7131                includedUsers = new HashSet<Integer>();
7132            }
7133            includedUsers.add(Integer.valueOf(userId));
7134            for (int i=0; i<N && maxNum > 0; i++) {
7135                TaskRecord tr = mRecentTasks.get(i);
7136                // Only add calling user or related users recent tasks
7137                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7138
7139                // Return the entry if desired by the caller.  We always return
7140                // the first entry, because callers always expect this to be the
7141                // foreground app.  We may filter others if the caller has
7142                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7143                // we should exclude the entry.
7144
7145                if (i == 0
7146                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7147                        || (tr.intent == null)
7148                        || ((tr.intent.getFlags()
7149                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7150                    if (!allowed) {
7151                        // If the caller doesn't have the GET_TASKS permission, then only
7152                        // allow them to see a small subset of tasks -- their own and home.
7153                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7154                            continue;
7155                        }
7156                    }
7157
7158                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7159                    if (!detailed) {
7160                        rti.baseIntent.replaceExtras((Bundle)null);
7161                    }
7162
7163                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7164                        // Check whether this activity is currently available.
7165                        try {
7166                            if (rti.origActivity != null) {
7167                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7168                                        == null) {
7169                                    continue;
7170                                }
7171                            } else if (rti.baseIntent != null) {
7172                                if (pm.queryIntentActivities(rti.baseIntent,
7173                                        null, 0, userId) == null) {
7174                                    continue;
7175                                }
7176                            }
7177                        } catch (RemoteException e) {
7178                            // Will never happen.
7179                        }
7180                    }
7181
7182                    res.add(rti);
7183                    maxNum--;
7184                }
7185            }
7186            return res;
7187        }
7188    }
7189
7190    private TaskRecord recentTaskForIdLocked(int id) {
7191        final int N = mRecentTasks.size();
7192            for (int i=0; i<N; i++) {
7193                TaskRecord tr = mRecentTasks.get(i);
7194                if (tr.taskId == id) {
7195                    return tr;
7196                }
7197            }
7198            return null;
7199    }
7200
7201    @Override
7202    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7203        synchronized (this) {
7204            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7205                    "getTaskThumbnails()");
7206            TaskRecord tr = recentTaskForIdLocked(id);
7207            if (tr != null) {
7208                return tr.getTaskThumbnailsLocked();
7209            }
7210        }
7211        return null;
7212    }
7213
7214    @Override
7215    public Bitmap getTaskTopThumbnail(int id) {
7216        synchronized (this) {
7217            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7218                    "getTaskTopThumbnail()");
7219            TaskRecord tr = recentTaskForIdLocked(id);
7220            if (tr != null) {
7221                return tr.getTaskTopThumbnailLocked();
7222            }
7223        }
7224        return null;
7225    }
7226
7227    @Override
7228    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7229        synchronized (this) {
7230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7231            if (r != null) {
7232                r.taskDescription = td;
7233                r.task.updateTaskDescription();
7234            }
7235        }
7236    }
7237
7238    @Override
7239    public boolean removeSubTask(int taskId, int subTaskIndex) {
7240        synchronized (this) {
7241            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7242                    "removeSubTask()");
7243            long ident = Binder.clearCallingIdentity();
7244            try {
7245                TaskRecord tr = recentTaskForIdLocked(taskId);
7246                if (tr != null) {
7247                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7248                }
7249                return false;
7250            } finally {
7251                Binder.restoreCallingIdentity(ident);
7252            }
7253        }
7254    }
7255
7256    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7257        if (!pr.killedByAm) {
7258            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7259            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7260                    pr.processName, pr.setAdj, reason);
7261            pr.killedByAm = true;
7262            Process.killProcessQuiet(pr.pid);
7263        }
7264    }
7265
7266    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7267        tr.disposeThumbnail();
7268        mRecentTasks.remove(tr);
7269        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7270        Intent baseIntent = new Intent(
7271                tr.intent != null ? tr.intent : tr.affinityIntent);
7272        ComponentName component = baseIntent.getComponent();
7273        if (component == null) {
7274            Slog.w(TAG, "Now component for base intent of task: " + tr);
7275            return;
7276        }
7277
7278        // Find any running services associated with this app.
7279        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7280
7281        if (killProcesses) {
7282            // Find any running processes associated with this app.
7283            final String pkg = component.getPackageName();
7284            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7285            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7286            for (int i=0; i<pmap.size(); i++) {
7287                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7288                for (int j=0; j<uids.size(); j++) {
7289                    ProcessRecord proc = uids.valueAt(j);
7290                    if (proc.userId != tr.userId) {
7291                        continue;
7292                    }
7293                    if (!proc.pkgList.containsKey(pkg)) {
7294                        continue;
7295                    }
7296                    procs.add(proc);
7297                }
7298            }
7299
7300            // Kill the running processes.
7301            for (int i=0; i<procs.size(); i++) {
7302                ProcessRecord pr = procs.get(i);
7303                if (pr == mHomeProcess) {
7304                    // Don't kill the home process along with tasks from the same package.
7305                    continue;
7306                }
7307                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7308                    killUnneededProcessLocked(pr, "remove task");
7309                } else {
7310                    pr.waitingToKill = "remove task";
7311                }
7312            }
7313        }
7314    }
7315
7316    /**
7317     * Removes the task with the specified task id.
7318     *
7319     * @param taskId Identifier of the task to be removed.
7320     * @param flags Additional operational flags.  May be 0 or
7321     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7322     * @return Returns true if the given task was found and removed.
7323     */
7324    private boolean removeTaskByIdLocked(int taskId, int flags) {
7325        TaskRecord tr = recentTaskForIdLocked(taskId);
7326        if (tr != null) {
7327            tr.removeTaskActivitiesLocked(-1, false);
7328            cleanUpRemovedTaskLocked(tr, flags);
7329            if (tr.isPersistable) {
7330                notifyTaskPersisterLocked(tr, true);
7331            }
7332            return true;
7333        }
7334        return false;
7335    }
7336
7337    @Override
7338    public boolean removeTask(int taskId, int flags) {
7339        synchronized (this) {
7340            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7341                    "removeTask()");
7342            long ident = Binder.clearCallingIdentity();
7343            try {
7344                return removeTaskByIdLocked(taskId, flags);
7345            } finally {
7346                Binder.restoreCallingIdentity(ident);
7347            }
7348        }
7349    }
7350
7351    /**
7352     * TODO: Add mController hook
7353     */
7354    @Override
7355    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7356        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7357                "moveTaskToFront()");
7358
7359        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7360        synchronized(this) {
7361            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7362                    Binder.getCallingUid(), "Task to front")) {
7363                ActivityOptions.abort(options);
7364                return;
7365            }
7366            final long origId = Binder.clearCallingIdentity();
7367            try {
7368                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7369                if (task == null) {
7370                    return;
7371                }
7372                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7373                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7374                    return;
7375                }
7376                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7377            } finally {
7378                Binder.restoreCallingIdentity(origId);
7379            }
7380            ActivityOptions.abort(options);
7381        }
7382    }
7383
7384    @Override
7385    public void moveTaskToBack(int taskId) {
7386        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7387                "moveTaskToBack()");
7388
7389        synchronized(this) {
7390            TaskRecord tr = recentTaskForIdLocked(taskId);
7391            if (tr != null) {
7392                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7393                ActivityStack stack = tr.stack;
7394                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7395                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7396                            Binder.getCallingUid(), "Task to back")) {
7397                        return;
7398                    }
7399                }
7400                final long origId = Binder.clearCallingIdentity();
7401                try {
7402                    stack.moveTaskToBackLocked(taskId, null);
7403                } finally {
7404                    Binder.restoreCallingIdentity(origId);
7405                }
7406            }
7407        }
7408    }
7409
7410    /**
7411     * Moves an activity, and all of the other activities within the same task, to the bottom
7412     * of the history stack.  The activity's order within the task is unchanged.
7413     *
7414     * @param token A reference to the activity we wish to move
7415     * @param nonRoot If false then this only works if the activity is the root
7416     *                of a task; if true it will work for any activity in a task.
7417     * @return Returns true if the move completed, false if not.
7418     */
7419    @Override
7420    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7421        enforceNotIsolatedCaller("moveActivityTaskToBack");
7422        synchronized(this) {
7423            final long origId = Binder.clearCallingIdentity();
7424            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7425            if (taskId >= 0) {
7426                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7427            }
7428            Binder.restoreCallingIdentity(origId);
7429        }
7430        return false;
7431    }
7432
7433    @Override
7434    public void moveTaskBackwards(int task) {
7435        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7436                "moveTaskBackwards()");
7437
7438        synchronized(this) {
7439            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7440                    Binder.getCallingUid(), "Task backwards")) {
7441                return;
7442            }
7443            final long origId = Binder.clearCallingIdentity();
7444            moveTaskBackwardsLocked(task);
7445            Binder.restoreCallingIdentity(origId);
7446        }
7447    }
7448
7449    private final void moveTaskBackwardsLocked(int task) {
7450        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7451    }
7452
7453    @Override
7454    public IBinder getHomeActivityToken() throws RemoteException {
7455        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7456                "getHomeActivityToken()");
7457        synchronized (this) {
7458            return mStackSupervisor.getHomeActivityToken();
7459        }
7460    }
7461
7462    @Override
7463    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7464            IActivityContainerCallback callback) throws RemoteException {
7465        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7466                "createActivityContainer()");
7467        synchronized (this) {
7468            if (parentActivityToken == null) {
7469                throw new IllegalArgumentException("parent token must not be null");
7470            }
7471            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7472            if (r == null) {
7473                return null;
7474            }
7475            if (callback == null) {
7476                throw new IllegalArgumentException("callback must not be null");
7477            }
7478            return mStackSupervisor.createActivityContainer(r, callback);
7479        }
7480    }
7481
7482    @Override
7483    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7484        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7485                "deleteActivityContainer()");
7486        synchronized (this) {
7487            mStackSupervisor.deleteActivityContainer(container);
7488        }
7489    }
7490
7491    @Override
7492    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7493            throws RemoteException {
7494        synchronized (this) {
7495            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7496            if (stack != null) {
7497                return stack.mActivityContainer;
7498            }
7499            return null;
7500        }
7501    }
7502
7503    @Override
7504    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7505        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7506                "moveTaskToStack()");
7507        if (stackId == HOME_STACK_ID) {
7508            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7509                    new RuntimeException("here").fillInStackTrace());
7510        }
7511        synchronized (this) {
7512            long ident = Binder.clearCallingIdentity();
7513            try {
7514                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7515                        + stackId + " toTop=" + toTop);
7516                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7517            } finally {
7518                Binder.restoreCallingIdentity(ident);
7519            }
7520        }
7521    }
7522
7523    @Override
7524    public void resizeStack(int stackBoxId, Rect bounds) {
7525        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7526                "resizeStackBox()");
7527        long ident = Binder.clearCallingIdentity();
7528        try {
7529            mWindowManager.resizeStack(stackBoxId, bounds);
7530        } finally {
7531            Binder.restoreCallingIdentity(ident);
7532        }
7533    }
7534
7535    @Override
7536    public List<StackInfo> getAllStackInfos() {
7537        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7538                "getAllStackInfos()");
7539        long ident = Binder.clearCallingIdentity();
7540        try {
7541            synchronized (this) {
7542                return mStackSupervisor.getAllStackInfosLocked();
7543            }
7544        } finally {
7545            Binder.restoreCallingIdentity(ident);
7546        }
7547    }
7548
7549    @Override
7550    public StackInfo getStackInfo(int stackId) {
7551        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7552                "getStackInfo()");
7553        long ident = Binder.clearCallingIdentity();
7554        try {
7555            synchronized (this) {
7556                return mStackSupervisor.getStackInfoLocked(stackId);
7557            }
7558        } finally {
7559            Binder.restoreCallingIdentity(ident);
7560        }
7561    }
7562
7563    @Override
7564    public boolean isInHomeStack(int taskId) {
7565        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7566                "getStackInfo()");
7567        long ident = Binder.clearCallingIdentity();
7568        try {
7569            synchronized (this) {
7570                TaskRecord tr = recentTaskForIdLocked(taskId);
7571                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7572            }
7573        } finally {
7574            Binder.restoreCallingIdentity(ident);
7575        }
7576    }
7577
7578    @Override
7579    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7580        synchronized(this) {
7581            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7582        }
7583    }
7584
7585    private boolean isLockTaskAuthorized(ComponentName name) {
7586        final DevicePolicyManager dpm = (DevicePolicyManager)
7587                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7588        return dpm != null && dpm.isLockTaskPermitted(name);
7589    }
7590
7591    private void startLockTaskMode(TaskRecord task) {
7592        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7593            return;
7594        }
7595        long ident = Binder.clearCallingIdentity();
7596        try {
7597            synchronized (this) {
7598                // Since we lost lock on task, make sure it is still there.
7599                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7600                if (task != null) {
7601                    mStackSupervisor.setLockTaskModeLocked(task);
7602                }
7603            }
7604        } finally {
7605            Binder.restoreCallingIdentity(ident);
7606        }
7607    }
7608
7609    @Override
7610    public void startLockTaskMode(int taskId) {
7611        long ident = Binder.clearCallingIdentity();
7612        try {
7613            final TaskRecord task;
7614            synchronized (this) {
7615                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7616            }
7617            if (task != null) {
7618                startLockTaskMode(task);
7619            }
7620        } finally {
7621            Binder.restoreCallingIdentity(ident);
7622        }
7623    }
7624
7625    @Override
7626    public void startLockTaskMode(IBinder token) {
7627        long ident = Binder.clearCallingIdentity();
7628        try {
7629            final TaskRecord task;
7630            synchronized (this) {
7631                final ActivityRecord r = ActivityRecord.forToken(token);
7632                if (r == null) {
7633                    return;
7634                }
7635                task = r.task;
7636            }
7637            if (task != null) {
7638                startLockTaskMode(task);
7639            }
7640        } finally {
7641            Binder.restoreCallingIdentity(ident);
7642        }
7643    }
7644
7645    @Override
7646    public void stopLockTaskMode() {
7647        // Check if the calling task is eligible to use lock task
7648        final int uid = Binder.getCallingUid();
7649        try {
7650            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7651            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7652                return;
7653            }
7654        } catch (RemoteException e) {
7655            Log.d(TAG, "stopLockTaskMode " + e);
7656            return;
7657        }
7658        // Stop lock task
7659        synchronized (this) {
7660            mStackSupervisor.setLockTaskModeLocked(null);
7661        }
7662    }
7663
7664    @Override
7665    public boolean isInLockTaskMode() {
7666        synchronized (this) {
7667            return mStackSupervisor.isInLockTaskMode();
7668        }
7669    }
7670
7671    // =========================================================
7672    // CONTENT PROVIDERS
7673    // =========================================================
7674
7675    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7676        List<ProviderInfo> providers = null;
7677        try {
7678            providers = AppGlobals.getPackageManager().
7679                queryContentProviders(app.processName, app.uid,
7680                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7681        } catch (RemoteException ex) {
7682        }
7683        if (DEBUG_MU)
7684            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7685        int userId = app.userId;
7686        if (providers != null) {
7687            int N = providers.size();
7688            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7689            for (int i=0; i<N; i++) {
7690                ProviderInfo cpi =
7691                    (ProviderInfo)providers.get(i);
7692                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7693                        cpi.name, cpi.flags);
7694                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7695                    // This is a singleton provider, but a user besides the
7696                    // default user is asking to initialize a process it runs
7697                    // in...  well, no, it doesn't actually run in this process,
7698                    // it runs in the process of the default user.  Get rid of it.
7699                    providers.remove(i);
7700                    N--;
7701                    i--;
7702                    continue;
7703                }
7704
7705                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7706                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7707                if (cpr == null) {
7708                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7709                    mProviderMap.putProviderByClass(comp, cpr);
7710                }
7711                if (DEBUG_MU)
7712                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7713                app.pubProviders.put(cpi.name, cpr);
7714                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7715                    // Don't add this if it is a platform component that is marked
7716                    // to run in multiple processes, because this is actually
7717                    // part of the framework so doesn't make sense to track as a
7718                    // separate apk in the process.
7719                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7720                }
7721                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7722            }
7723        }
7724        return providers;
7725    }
7726
7727    /**
7728     * Check if {@link ProcessRecord} has a possible chance at accessing the
7729     * given {@link ProviderInfo}. Final permission checking is always done
7730     * in {@link ContentProvider}.
7731     */
7732    private final String checkContentProviderPermissionLocked(
7733            ProviderInfo cpi, ProcessRecord r, int userId) {
7734        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7735        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7736        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7737        // Looking for cross-user grants before to enforce the typical cross-users permissions
7738        if (userId != UserHandle.getUserId(callingUid)) {
7739            if (perms != null) {
7740                for (GrantUri grantUri : perms.keySet()) {
7741                    if (grantUri.sourceUserId == userId) {
7742                        String authority = grantUri.uri.getAuthority();
7743                        if (authority.equals(cpi.authority)) {
7744                            return null;
7745                        }
7746                    }
7747                }
7748            }
7749        }
7750        userId = handleIncomingUser(callingPid, callingUid, userId,
7751                false, true, "checkContentProviderPermissionLocked", null);
7752        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7753                cpi.applicationInfo.uid, cpi.exported)
7754                == PackageManager.PERMISSION_GRANTED) {
7755            return null;
7756        }
7757        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7758                cpi.applicationInfo.uid, cpi.exported)
7759                == PackageManager.PERMISSION_GRANTED) {
7760            return null;
7761        }
7762
7763        PathPermission[] pps = cpi.pathPermissions;
7764        if (pps != null) {
7765            int i = pps.length;
7766            while (i > 0) {
7767                i--;
7768                PathPermission pp = pps[i];
7769                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7770                        cpi.applicationInfo.uid, cpi.exported)
7771                        == PackageManager.PERMISSION_GRANTED) {
7772                    return null;
7773                }
7774                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7775                        cpi.applicationInfo.uid, cpi.exported)
7776                        == PackageManager.PERMISSION_GRANTED) {
7777                    return null;
7778                }
7779            }
7780        }
7781
7782        if (perms != null) {
7783            for (GrantUri grantUri : perms.keySet()) {
7784                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7785                    return null;
7786                }
7787            }
7788        }
7789
7790        String msg;
7791        if (!cpi.exported) {
7792            msg = "Permission Denial: opening provider " + cpi.name
7793                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7794                    + ", uid=" + callingUid + ") that is not exported from uid "
7795                    + cpi.applicationInfo.uid;
7796        } else {
7797            msg = "Permission Denial: opening provider " + cpi.name
7798                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7799                    + ", uid=" + callingUid + ") requires "
7800                    + cpi.readPermission + " or " + cpi.writePermission;
7801        }
7802        Slog.w(TAG, msg);
7803        return msg;
7804    }
7805
7806    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7807            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7808        if (r != null) {
7809            for (int i=0; i<r.conProviders.size(); i++) {
7810                ContentProviderConnection conn = r.conProviders.get(i);
7811                if (conn.provider == cpr) {
7812                    if (DEBUG_PROVIDER) Slog.v(TAG,
7813                            "Adding provider requested by "
7814                            + r.processName + " from process "
7815                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7816                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7817                    if (stable) {
7818                        conn.stableCount++;
7819                        conn.numStableIncs++;
7820                    } else {
7821                        conn.unstableCount++;
7822                        conn.numUnstableIncs++;
7823                    }
7824                    return conn;
7825                }
7826            }
7827            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7828            if (stable) {
7829                conn.stableCount = 1;
7830                conn.numStableIncs = 1;
7831            } else {
7832                conn.unstableCount = 1;
7833                conn.numUnstableIncs = 1;
7834            }
7835            cpr.connections.add(conn);
7836            r.conProviders.add(conn);
7837            return conn;
7838        }
7839        cpr.addExternalProcessHandleLocked(externalProcessToken);
7840        return null;
7841    }
7842
7843    boolean decProviderCountLocked(ContentProviderConnection conn,
7844            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7845        if (conn != null) {
7846            cpr = conn.provider;
7847            if (DEBUG_PROVIDER) Slog.v(TAG,
7848                    "Removing provider requested by "
7849                    + conn.client.processName + " from process "
7850                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7851                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7852            if (stable) {
7853                conn.stableCount--;
7854            } else {
7855                conn.unstableCount--;
7856            }
7857            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7858                cpr.connections.remove(conn);
7859                conn.client.conProviders.remove(conn);
7860                return true;
7861            }
7862            return false;
7863        }
7864        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7865        return false;
7866    }
7867
7868    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7869            String name, IBinder token, boolean stable, int userId) {
7870        ContentProviderRecord cpr;
7871        ContentProviderConnection conn = null;
7872        ProviderInfo cpi = null;
7873
7874        synchronized(this) {
7875            ProcessRecord r = null;
7876            if (caller != null) {
7877                r = getRecordForAppLocked(caller);
7878                if (r == null) {
7879                    throw new SecurityException(
7880                            "Unable to find app for caller " + caller
7881                          + " (pid=" + Binder.getCallingPid()
7882                          + ") when getting content provider " + name);
7883                }
7884            }
7885
7886            // First check if this content provider has been published...
7887            cpr = mProviderMap.getProviderByName(name, userId);
7888            boolean providerRunning = cpr != null;
7889            if (providerRunning) {
7890                cpi = cpr.info;
7891                String msg;
7892                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7893                    throw new SecurityException(msg);
7894                }
7895
7896                if (r != null && cpr.canRunHere(r)) {
7897                    // This provider has been published or is in the process
7898                    // of being published...  but it is also allowed to run
7899                    // in the caller's process, so don't make a connection
7900                    // and just let the caller instantiate its own instance.
7901                    ContentProviderHolder holder = cpr.newHolder(null);
7902                    // don't give caller the provider object, it needs
7903                    // to make its own.
7904                    holder.provider = null;
7905                    return holder;
7906                }
7907
7908                final long origId = Binder.clearCallingIdentity();
7909
7910                // In this case the provider instance already exists, so we can
7911                // return it right away.
7912                conn = incProviderCountLocked(r, cpr, token, stable);
7913                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7914                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7915                        // If this is a perceptible app accessing the provider,
7916                        // make sure to count it as being accessed and thus
7917                        // back up on the LRU list.  This is good because
7918                        // content providers are often expensive to start.
7919                        updateLruProcessLocked(cpr.proc, false, null);
7920                    }
7921                }
7922
7923                if (cpr.proc != null) {
7924                    if (false) {
7925                        if (cpr.name.flattenToShortString().equals(
7926                                "com.android.providers.calendar/.CalendarProvider2")) {
7927                            Slog.v(TAG, "****************** KILLING "
7928                                + cpr.name.flattenToShortString());
7929                            Process.killProcess(cpr.proc.pid);
7930                        }
7931                    }
7932                    boolean success = updateOomAdjLocked(cpr.proc);
7933                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7934                    // NOTE: there is still a race here where a signal could be
7935                    // pending on the process even though we managed to update its
7936                    // adj level.  Not sure what to do about this, but at least
7937                    // the race is now smaller.
7938                    if (!success) {
7939                        // Uh oh...  it looks like the provider's process
7940                        // has been killed on us.  We need to wait for a new
7941                        // process to be started, and make sure its death
7942                        // doesn't kill our process.
7943                        Slog.i(TAG,
7944                                "Existing provider " + cpr.name.flattenToShortString()
7945                                + " is crashing; detaching " + r);
7946                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7947                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7948                        if (!lastRef) {
7949                            // This wasn't the last ref our process had on
7950                            // the provider...  we have now been killed, bail.
7951                            return null;
7952                        }
7953                        providerRunning = false;
7954                        conn = null;
7955                    }
7956                }
7957
7958                Binder.restoreCallingIdentity(origId);
7959            }
7960
7961            boolean singleton;
7962            if (!providerRunning) {
7963                try {
7964                    cpi = AppGlobals.getPackageManager().
7965                        resolveContentProvider(name,
7966                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7967                } catch (RemoteException ex) {
7968                }
7969                if (cpi == null) {
7970                    return null;
7971                }
7972                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7973                        cpi.name, cpi.flags);
7974                if (singleton) {
7975                    userId = 0;
7976                }
7977                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7978
7979                String msg;
7980                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7981                    throw new SecurityException(msg);
7982                }
7983
7984                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7985                        && !cpi.processName.equals("system")) {
7986                    // If this content provider does not run in the system
7987                    // process, and the system is not yet ready to run other
7988                    // processes, then fail fast instead of hanging.
7989                    throw new IllegalArgumentException(
7990                            "Attempt to launch content provider before system ready");
7991                }
7992
7993                // Make sure that the user who owns this provider is started.  If not,
7994                // we don't want to allow it to run.
7995                if (mStartedUsers.get(userId) == null) {
7996                    Slog.w(TAG, "Unable to launch app "
7997                            + cpi.applicationInfo.packageName + "/"
7998                            + cpi.applicationInfo.uid + " for provider "
7999                            + name + ": user " + userId + " is stopped");
8000                    return null;
8001                }
8002
8003                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8004                cpr = mProviderMap.getProviderByClass(comp, userId);
8005                final boolean firstClass = cpr == null;
8006                if (firstClass) {
8007                    try {
8008                        ApplicationInfo ai =
8009                            AppGlobals.getPackageManager().
8010                                getApplicationInfo(
8011                                        cpi.applicationInfo.packageName,
8012                                        STOCK_PM_FLAGS, userId);
8013                        if (ai == null) {
8014                            Slog.w(TAG, "No package info for content provider "
8015                                    + cpi.name);
8016                            return null;
8017                        }
8018                        ai = getAppInfoForUser(ai, userId);
8019                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8020                    } catch (RemoteException ex) {
8021                        // pm is in same process, this will never happen.
8022                    }
8023                }
8024
8025                if (r != null && cpr.canRunHere(r)) {
8026                    // If this is a multiprocess provider, then just return its
8027                    // info and allow the caller to instantiate it.  Only do
8028                    // this if the provider is the same user as the caller's
8029                    // process, or can run as root (so can be in any process).
8030                    return cpr.newHolder(null);
8031                }
8032
8033                if (DEBUG_PROVIDER) {
8034                    RuntimeException e = new RuntimeException("here");
8035                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8036                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8037                }
8038
8039                // This is single process, and our app is now connecting to it.
8040                // See if we are already in the process of launching this
8041                // provider.
8042                final int N = mLaunchingProviders.size();
8043                int i;
8044                for (i=0; i<N; i++) {
8045                    if (mLaunchingProviders.get(i) == cpr) {
8046                        break;
8047                    }
8048                }
8049
8050                // If the provider is not already being launched, then get it
8051                // started.
8052                if (i >= N) {
8053                    final long origId = Binder.clearCallingIdentity();
8054
8055                    try {
8056                        // Content provider is now in use, its package can't be stopped.
8057                        try {
8058                            AppGlobals.getPackageManager().setPackageStoppedState(
8059                                    cpr.appInfo.packageName, false, userId);
8060                        } catch (RemoteException e) {
8061                        } catch (IllegalArgumentException e) {
8062                            Slog.w(TAG, "Failed trying to unstop package "
8063                                    + cpr.appInfo.packageName + ": " + e);
8064                        }
8065
8066                        // Use existing process if already started
8067                        ProcessRecord proc = getProcessRecordLocked(
8068                                cpi.processName, cpr.appInfo.uid, false);
8069                        if (proc != null && proc.thread != null) {
8070                            if (DEBUG_PROVIDER) {
8071                                Slog.d(TAG, "Installing in existing process " + proc);
8072                            }
8073                            proc.pubProviders.put(cpi.name, cpr);
8074                            try {
8075                                proc.thread.scheduleInstallProvider(cpi);
8076                            } catch (RemoteException e) {
8077                            }
8078                        } else {
8079                            proc = startProcessLocked(cpi.processName,
8080                                    cpr.appInfo, false, 0, "content provider",
8081                                    new ComponentName(cpi.applicationInfo.packageName,
8082                                            cpi.name), false, false, false);
8083                            if (proc == null) {
8084                                Slog.w(TAG, "Unable to launch app "
8085                                        + cpi.applicationInfo.packageName + "/"
8086                                        + cpi.applicationInfo.uid + " for provider "
8087                                        + name + ": process is bad");
8088                                return null;
8089                            }
8090                        }
8091                        cpr.launchingApp = proc;
8092                        mLaunchingProviders.add(cpr);
8093                    } finally {
8094                        Binder.restoreCallingIdentity(origId);
8095                    }
8096                }
8097
8098                // Make sure the provider is published (the same provider class
8099                // may be published under multiple names).
8100                if (firstClass) {
8101                    mProviderMap.putProviderByClass(comp, cpr);
8102                }
8103
8104                mProviderMap.putProviderByName(name, cpr);
8105                conn = incProviderCountLocked(r, cpr, token, stable);
8106                if (conn != null) {
8107                    conn.waiting = true;
8108                }
8109            }
8110        }
8111
8112        // Wait for the provider to be published...
8113        synchronized (cpr) {
8114            while (cpr.provider == null) {
8115                if (cpr.launchingApp == null) {
8116                    Slog.w(TAG, "Unable to launch app "
8117                            + cpi.applicationInfo.packageName + "/"
8118                            + cpi.applicationInfo.uid + " for provider "
8119                            + name + ": launching app became null");
8120                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8121                            UserHandle.getUserId(cpi.applicationInfo.uid),
8122                            cpi.applicationInfo.packageName,
8123                            cpi.applicationInfo.uid, name);
8124                    return null;
8125                }
8126                try {
8127                    if (DEBUG_MU) {
8128                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8129                                + cpr.launchingApp);
8130                    }
8131                    if (conn != null) {
8132                        conn.waiting = true;
8133                    }
8134                    cpr.wait();
8135                } catch (InterruptedException ex) {
8136                } finally {
8137                    if (conn != null) {
8138                        conn.waiting = false;
8139                    }
8140                }
8141            }
8142        }
8143        return cpr != null ? cpr.newHolder(conn) : null;
8144    }
8145
8146    @Override
8147    public final ContentProviderHolder getContentProvider(
8148            IApplicationThread caller, String name, int userId, boolean stable) {
8149        enforceNotIsolatedCaller("getContentProvider");
8150        if (caller == null) {
8151            String msg = "null IApplicationThread when getting content provider "
8152                    + name;
8153            Slog.w(TAG, msg);
8154            throw new SecurityException(msg);
8155        }
8156        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8157        // with cross-user grant.
8158        return getContentProviderImpl(caller, name, null, stable, userId);
8159    }
8160
8161    public ContentProviderHolder getContentProviderExternal(
8162            String name, int userId, IBinder token) {
8163        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8164            "Do not have permission in call getContentProviderExternal()");
8165        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8166                false, true, "getContentProvider", null);
8167        return getContentProviderExternalUnchecked(name, token, userId);
8168    }
8169
8170    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8171            IBinder token, int userId) {
8172        return getContentProviderImpl(null, name, token, true, userId);
8173    }
8174
8175    /**
8176     * Drop a content provider from a ProcessRecord's bookkeeping
8177     */
8178    public void removeContentProvider(IBinder connection, boolean stable) {
8179        enforceNotIsolatedCaller("removeContentProvider");
8180        long ident = Binder.clearCallingIdentity();
8181        try {
8182            synchronized (this) {
8183                ContentProviderConnection conn;
8184                try {
8185                    conn = (ContentProviderConnection)connection;
8186                } catch (ClassCastException e) {
8187                    String msg ="removeContentProvider: " + connection
8188                            + " not a ContentProviderConnection";
8189                    Slog.w(TAG, msg);
8190                    throw new IllegalArgumentException(msg);
8191                }
8192                if (conn == null) {
8193                    throw new NullPointerException("connection is null");
8194                }
8195                if (decProviderCountLocked(conn, null, null, stable)) {
8196                    updateOomAdjLocked();
8197                }
8198            }
8199        } finally {
8200            Binder.restoreCallingIdentity(ident);
8201        }
8202    }
8203
8204    public void removeContentProviderExternal(String name, IBinder token) {
8205        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8206            "Do not have permission in call removeContentProviderExternal()");
8207        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8208    }
8209
8210    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8211        synchronized (this) {
8212            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8213            if(cpr == null) {
8214                //remove from mProvidersByClass
8215                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8216                return;
8217            }
8218
8219            //update content provider record entry info
8220            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8221            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8222            if (localCpr.hasExternalProcessHandles()) {
8223                if (localCpr.removeExternalProcessHandleLocked(token)) {
8224                    updateOomAdjLocked();
8225                } else {
8226                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8227                            + " with no external reference for token: "
8228                            + token + ".");
8229                }
8230            } else {
8231                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8232                        + " with no external references.");
8233            }
8234        }
8235    }
8236
8237    public final void publishContentProviders(IApplicationThread caller,
8238            List<ContentProviderHolder> providers) {
8239        if (providers == null) {
8240            return;
8241        }
8242
8243        enforceNotIsolatedCaller("publishContentProviders");
8244        synchronized (this) {
8245            final ProcessRecord r = getRecordForAppLocked(caller);
8246            if (DEBUG_MU)
8247                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8248            if (r == null) {
8249                throw new SecurityException(
8250                        "Unable to find app for caller " + caller
8251                      + " (pid=" + Binder.getCallingPid()
8252                      + ") when publishing content providers");
8253            }
8254
8255            final long origId = Binder.clearCallingIdentity();
8256
8257            final int N = providers.size();
8258            for (int i=0; i<N; i++) {
8259                ContentProviderHolder src = providers.get(i);
8260                if (src == null || src.info == null || src.provider == null) {
8261                    continue;
8262                }
8263                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8264                if (DEBUG_MU)
8265                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8266                if (dst != null) {
8267                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8268                    mProviderMap.putProviderByClass(comp, dst);
8269                    String names[] = dst.info.authority.split(";");
8270                    for (int j = 0; j < names.length; j++) {
8271                        mProviderMap.putProviderByName(names[j], dst);
8272                    }
8273
8274                    int NL = mLaunchingProviders.size();
8275                    int j;
8276                    for (j=0; j<NL; j++) {
8277                        if (mLaunchingProviders.get(j) == dst) {
8278                            mLaunchingProviders.remove(j);
8279                            j--;
8280                            NL--;
8281                        }
8282                    }
8283                    synchronized (dst) {
8284                        dst.provider = src.provider;
8285                        dst.proc = r;
8286                        dst.notifyAll();
8287                    }
8288                    updateOomAdjLocked(r);
8289                }
8290            }
8291
8292            Binder.restoreCallingIdentity(origId);
8293        }
8294    }
8295
8296    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8297        ContentProviderConnection conn;
8298        try {
8299            conn = (ContentProviderConnection)connection;
8300        } catch (ClassCastException e) {
8301            String msg ="refContentProvider: " + connection
8302                    + " not a ContentProviderConnection";
8303            Slog.w(TAG, msg);
8304            throw new IllegalArgumentException(msg);
8305        }
8306        if (conn == null) {
8307            throw new NullPointerException("connection is null");
8308        }
8309
8310        synchronized (this) {
8311            if (stable > 0) {
8312                conn.numStableIncs += stable;
8313            }
8314            stable = conn.stableCount + stable;
8315            if (stable < 0) {
8316                throw new IllegalStateException("stableCount < 0: " + stable);
8317            }
8318
8319            if (unstable > 0) {
8320                conn.numUnstableIncs += unstable;
8321            }
8322            unstable = conn.unstableCount + unstable;
8323            if (unstable < 0) {
8324                throw new IllegalStateException("unstableCount < 0: " + unstable);
8325            }
8326
8327            if ((stable+unstable) <= 0) {
8328                throw new IllegalStateException("ref counts can't go to zero here: stable="
8329                        + stable + " unstable=" + unstable);
8330            }
8331            conn.stableCount = stable;
8332            conn.unstableCount = unstable;
8333            return !conn.dead;
8334        }
8335    }
8336
8337    public void unstableProviderDied(IBinder connection) {
8338        ContentProviderConnection conn;
8339        try {
8340            conn = (ContentProviderConnection)connection;
8341        } catch (ClassCastException e) {
8342            String msg ="refContentProvider: " + connection
8343                    + " not a ContentProviderConnection";
8344            Slog.w(TAG, msg);
8345            throw new IllegalArgumentException(msg);
8346        }
8347        if (conn == null) {
8348            throw new NullPointerException("connection is null");
8349        }
8350
8351        // Safely retrieve the content provider associated with the connection.
8352        IContentProvider provider;
8353        synchronized (this) {
8354            provider = conn.provider.provider;
8355        }
8356
8357        if (provider == null) {
8358            // Um, yeah, we're way ahead of you.
8359            return;
8360        }
8361
8362        // Make sure the caller is being honest with us.
8363        if (provider.asBinder().pingBinder()) {
8364            // Er, no, still looks good to us.
8365            synchronized (this) {
8366                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8367                        + " says " + conn + " died, but we don't agree");
8368                return;
8369            }
8370        }
8371
8372        // Well look at that!  It's dead!
8373        synchronized (this) {
8374            if (conn.provider.provider != provider) {
8375                // But something changed...  good enough.
8376                return;
8377            }
8378
8379            ProcessRecord proc = conn.provider.proc;
8380            if (proc == null || proc.thread == null) {
8381                // Seems like the process is already cleaned up.
8382                return;
8383            }
8384
8385            // As far as we're concerned, this is just like receiving a
8386            // death notification...  just a bit prematurely.
8387            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8388                    + ") early provider death");
8389            final long ident = Binder.clearCallingIdentity();
8390            try {
8391                appDiedLocked(proc, proc.pid, proc.thread);
8392            } finally {
8393                Binder.restoreCallingIdentity(ident);
8394            }
8395        }
8396    }
8397
8398    @Override
8399    public void appNotRespondingViaProvider(IBinder connection) {
8400        enforceCallingPermission(
8401                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8402
8403        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8404        if (conn == null) {
8405            Slog.w(TAG, "ContentProviderConnection is null");
8406            return;
8407        }
8408
8409        final ProcessRecord host = conn.provider.proc;
8410        if (host == null) {
8411            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8412            return;
8413        }
8414
8415        final long token = Binder.clearCallingIdentity();
8416        try {
8417            appNotResponding(host, null, null, false, "ContentProvider not responding");
8418        } finally {
8419            Binder.restoreCallingIdentity(token);
8420        }
8421    }
8422
8423    public final void installSystemProviders() {
8424        List<ProviderInfo> providers;
8425        synchronized (this) {
8426            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8427            providers = generateApplicationProvidersLocked(app);
8428            if (providers != null) {
8429                for (int i=providers.size()-1; i>=0; i--) {
8430                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8431                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8432                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8433                                + ": not system .apk");
8434                        providers.remove(i);
8435                    }
8436                }
8437            }
8438        }
8439        if (providers != null) {
8440            mSystemThread.installSystemProviders(providers);
8441        }
8442
8443        mCoreSettingsObserver = new CoreSettingsObserver(this);
8444
8445        mUsageStatsService.monitorPackages();
8446    }
8447
8448    /**
8449     * Allows app to retrieve the MIME type of a URI without having permission
8450     * to access its content provider.
8451     *
8452     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8453     *
8454     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8455     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8456     */
8457    public String getProviderMimeType(Uri uri, int userId) {
8458        enforceNotIsolatedCaller("getProviderMimeType");
8459        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8460                userId, false, true, "getProviderMimeType", null);
8461        final String name = uri.getAuthority();
8462        final long ident = Binder.clearCallingIdentity();
8463        ContentProviderHolder holder = null;
8464
8465        try {
8466            holder = getContentProviderExternalUnchecked(name, null, userId);
8467            if (holder != null) {
8468                return holder.provider.getType(uri);
8469            }
8470        } catch (RemoteException e) {
8471            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8472            return null;
8473        } finally {
8474            if (holder != null) {
8475                removeContentProviderExternalUnchecked(name, null, userId);
8476            }
8477            Binder.restoreCallingIdentity(ident);
8478        }
8479
8480        return null;
8481    }
8482
8483    // =========================================================
8484    // GLOBAL MANAGEMENT
8485    // =========================================================
8486
8487    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8488            boolean isolated) {
8489        String proc = customProcess != null ? customProcess : info.processName;
8490        BatteryStatsImpl.Uid.Proc ps = null;
8491        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8492        int uid = info.uid;
8493        if (isolated) {
8494            int userId = UserHandle.getUserId(uid);
8495            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8496            while (true) {
8497                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8498                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8499                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8500                }
8501                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8502                mNextIsolatedProcessUid++;
8503                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8504                    // No process for this uid, use it.
8505                    break;
8506                }
8507                stepsLeft--;
8508                if (stepsLeft <= 0) {
8509                    return null;
8510                }
8511            }
8512        }
8513        return new ProcessRecord(stats, info, proc, uid);
8514    }
8515
8516    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8517        ProcessRecord app;
8518        if (!isolated) {
8519            app = getProcessRecordLocked(info.processName, info.uid, true);
8520        } else {
8521            app = null;
8522        }
8523
8524        if (app == null) {
8525            app = newProcessRecordLocked(info, null, isolated);
8526            mProcessNames.put(info.processName, app.uid, app);
8527            if (isolated) {
8528                mIsolatedProcesses.put(app.uid, app);
8529            }
8530            updateLruProcessLocked(app, false, null);
8531            updateOomAdjLocked();
8532        }
8533
8534        // This package really, really can not be stopped.
8535        try {
8536            AppGlobals.getPackageManager().setPackageStoppedState(
8537                    info.packageName, false, UserHandle.getUserId(app.uid));
8538        } catch (RemoteException e) {
8539        } catch (IllegalArgumentException e) {
8540            Slog.w(TAG, "Failed trying to unstop package "
8541                    + info.packageName + ": " + e);
8542        }
8543
8544        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8545                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8546            app.persistent = true;
8547            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8548        }
8549        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8550            mPersistentStartingProcesses.add(app);
8551            startProcessLocked(app, "added application", app.processName);
8552        }
8553
8554        return app;
8555    }
8556
8557    public void unhandledBack() {
8558        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8559                "unhandledBack()");
8560
8561        synchronized(this) {
8562            final long origId = Binder.clearCallingIdentity();
8563            try {
8564                getFocusedStack().unhandledBackLocked();
8565            } finally {
8566                Binder.restoreCallingIdentity(origId);
8567            }
8568        }
8569    }
8570
8571    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8572        enforceNotIsolatedCaller("openContentUri");
8573        final int userId = UserHandle.getCallingUserId();
8574        String name = uri.getAuthority();
8575        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8576        ParcelFileDescriptor pfd = null;
8577        if (cph != null) {
8578            // We record the binder invoker's uid in thread-local storage before
8579            // going to the content provider to open the file.  Later, in the code
8580            // that handles all permissions checks, we look for this uid and use
8581            // that rather than the Activity Manager's own uid.  The effect is that
8582            // we do the check against the caller's permissions even though it looks
8583            // to the content provider like the Activity Manager itself is making
8584            // the request.
8585            sCallerIdentity.set(new Identity(
8586                    Binder.getCallingPid(), Binder.getCallingUid()));
8587            try {
8588                pfd = cph.provider.openFile(null, uri, "r", null);
8589            } catch (FileNotFoundException e) {
8590                // do nothing; pfd will be returned null
8591            } finally {
8592                // Ensure that whatever happens, we clean up the identity state
8593                sCallerIdentity.remove();
8594            }
8595
8596            // We've got the fd now, so we're done with the provider.
8597            removeContentProviderExternalUnchecked(name, null, userId);
8598        } else {
8599            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8600        }
8601        return pfd;
8602    }
8603
8604    // Actually is sleeping or shutting down or whatever else in the future
8605    // is an inactive state.
8606    public boolean isSleepingOrShuttingDown() {
8607        return mSleeping || mShuttingDown;
8608    }
8609
8610    public boolean isSleeping() {
8611        return mSleeping;
8612    }
8613
8614    void goingToSleep() {
8615        synchronized(this) {
8616            mWentToSleep = true;
8617            updateEventDispatchingLocked();
8618            goToSleepIfNeededLocked();
8619        }
8620    }
8621
8622    void finishRunningVoiceLocked() {
8623        if (mRunningVoice) {
8624            mRunningVoice = false;
8625            goToSleepIfNeededLocked();
8626        }
8627    }
8628
8629    void goToSleepIfNeededLocked() {
8630        if (mWentToSleep && !mRunningVoice) {
8631            if (!mSleeping) {
8632                mSleeping = true;
8633                mStackSupervisor.goingToSleepLocked();
8634
8635                // Initialize the wake times of all processes.
8636                checkExcessivePowerUsageLocked(false);
8637                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8638                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8639                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8640            }
8641        }
8642    }
8643
8644    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8645        mTaskPersister.notify(task, flush);
8646    }
8647
8648    @Override
8649    public boolean shutdown(int timeout) {
8650        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8651                != PackageManager.PERMISSION_GRANTED) {
8652            throw new SecurityException("Requires permission "
8653                    + android.Manifest.permission.SHUTDOWN);
8654        }
8655
8656        boolean timedout = false;
8657
8658        synchronized(this) {
8659            mShuttingDown = true;
8660            updateEventDispatchingLocked();
8661            timedout = mStackSupervisor.shutdownLocked(timeout);
8662        }
8663
8664        mAppOpsService.shutdown();
8665        mUsageStatsService.shutdown();
8666        mBatteryStatsService.shutdown();
8667        synchronized (this) {
8668            mProcessStats.shutdownLocked();
8669        }
8670        notifyTaskPersisterLocked(null, true);
8671
8672        return timedout;
8673    }
8674
8675    public final void activitySlept(IBinder token) {
8676        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8677
8678        final long origId = Binder.clearCallingIdentity();
8679
8680        synchronized (this) {
8681            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8682            if (r != null) {
8683                mStackSupervisor.activitySleptLocked(r);
8684            }
8685        }
8686
8687        Binder.restoreCallingIdentity(origId);
8688    }
8689
8690    void logLockScreen(String msg) {
8691        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8692                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8693                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8694                mStackSupervisor.mDismissKeyguardOnNextActivity);
8695    }
8696
8697    private void comeOutOfSleepIfNeededLocked() {
8698        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8699            if (mSleeping) {
8700                mSleeping = false;
8701                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8702            }
8703        }
8704    }
8705
8706    void wakingUp() {
8707        synchronized(this) {
8708            mWentToSleep = false;
8709            updateEventDispatchingLocked();
8710            comeOutOfSleepIfNeededLocked();
8711        }
8712    }
8713
8714    void startRunningVoiceLocked() {
8715        if (!mRunningVoice) {
8716            mRunningVoice = true;
8717            comeOutOfSleepIfNeededLocked();
8718        }
8719    }
8720
8721    private void updateEventDispatchingLocked() {
8722        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8723    }
8724
8725    public void setLockScreenShown(boolean shown) {
8726        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8727                != PackageManager.PERMISSION_GRANTED) {
8728            throw new SecurityException("Requires permission "
8729                    + android.Manifest.permission.DEVICE_POWER);
8730        }
8731
8732        synchronized(this) {
8733            long ident = Binder.clearCallingIdentity();
8734            try {
8735                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8736                mLockScreenShown = shown;
8737                comeOutOfSleepIfNeededLocked();
8738            } finally {
8739                Binder.restoreCallingIdentity(ident);
8740            }
8741        }
8742    }
8743
8744    public void stopAppSwitches() {
8745        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8746                != PackageManager.PERMISSION_GRANTED) {
8747            throw new SecurityException("Requires permission "
8748                    + android.Manifest.permission.STOP_APP_SWITCHES);
8749        }
8750
8751        synchronized(this) {
8752            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8753                    + APP_SWITCH_DELAY_TIME;
8754            mDidAppSwitch = false;
8755            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8756            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8757            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8758        }
8759    }
8760
8761    public void resumeAppSwitches() {
8762        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8763                != PackageManager.PERMISSION_GRANTED) {
8764            throw new SecurityException("Requires permission "
8765                    + android.Manifest.permission.STOP_APP_SWITCHES);
8766        }
8767
8768        synchronized(this) {
8769            // Note that we don't execute any pending app switches... we will
8770            // let those wait until either the timeout, or the next start
8771            // activity request.
8772            mAppSwitchesAllowedTime = 0;
8773        }
8774    }
8775
8776    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8777            String name) {
8778        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8779            return true;
8780        }
8781
8782        final int perm = checkComponentPermission(
8783                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8784                callingUid, -1, true);
8785        if (perm == PackageManager.PERMISSION_GRANTED) {
8786            return true;
8787        }
8788
8789        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8790        return false;
8791    }
8792
8793    public void setDebugApp(String packageName, boolean waitForDebugger,
8794            boolean persistent) {
8795        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8796                "setDebugApp()");
8797
8798        long ident = Binder.clearCallingIdentity();
8799        try {
8800            // Note that this is not really thread safe if there are multiple
8801            // callers into it at the same time, but that's not a situation we
8802            // care about.
8803            if (persistent) {
8804                final ContentResolver resolver = mContext.getContentResolver();
8805                Settings.Global.putString(
8806                    resolver, Settings.Global.DEBUG_APP,
8807                    packageName);
8808                Settings.Global.putInt(
8809                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8810                    waitForDebugger ? 1 : 0);
8811            }
8812
8813            synchronized (this) {
8814                if (!persistent) {
8815                    mOrigDebugApp = mDebugApp;
8816                    mOrigWaitForDebugger = mWaitForDebugger;
8817                }
8818                mDebugApp = packageName;
8819                mWaitForDebugger = waitForDebugger;
8820                mDebugTransient = !persistent;
8821                if (packageName != null) {
8822                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8823                            false, UserHandle.USER_ALL, "set debug app");
8824                }
8825            }
8826        } finally {
8827            Binder.restoreCallingIdentity(ident);
8828        }
8829    }
8830
8831    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8832        synchronized (this) {
8833            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8834            if (!isDebuggable) {
8835                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8836                    throw new SecurityException("Process not debuggable: " + app.packageName);
8837                }
8838            }
8839
8840            mOpenGlTraceApp = processName;
8841        }
8842    }
8843
8844    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8845            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8846        synchronized (this) {
8847            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8848            if (!isDebuggable) {
8849                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8850                    throw new SecurityException("Process not debuggable: " + app.packageName);
8851                }
8852            }
8853            mProfileApp = processName;
8854            mProfileFile = profileFile;
8855            if (mProfileFd != null) {
8856                try {
8857                    mProfileFd.close();
8858                } catch (IOException e) {
8859                }
8860                mProfileFd = null;
8861            }
8862            mProfileFd = profileFd;
8863            mProfileType = 0;
8864            mAutoStopProfiler = autoStopProfiler;
8865        }
8866    }
8867
8868    @Override
8869    public void setAlwaysFinish(boolean enabled) {
8870        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8871                "setAlwaysFinish()");
8872
8873        Settings.Global.putInt(
8874                mContext.getContentResolver(),
8875                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8876
8877        synchronized (this) {
8878            mAlwaysFinishActivities = enabled;
8879        }
8880    }
8881
8882    @Override
8883    public void setActivityController(IActivityController controller) {
8884        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8885                "setActivityController()");
8886        synchronized (this) {
8887            mController = controller;
8888            Watchdog.getInstance().setActivityController(controller);
8889        }
8890    }
8891
8892    @Override
8893    public void setUserIsMonkey(boolean userIsMonkey) {
8894        synchronized (this) {
8895            synchronized (mPidsSelfLocked) {
8896                final int callingPid = Binder.getCallingPid();
8897                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8898                if (precessRecord == null) {
8899                    throw new SecurityException("Unknown process: " + callingPid);
8900                }
8901                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8902                    throw new SecurityException("Only an instrumentation process "
8903                            + "with a UiAutomation can call setUserIsMonkey");
8904                }
8905            }
8906            mUserIsMonkey = userIsMonkey;
8907        }
8908    }
8909
8910    @Override
8911    public boolean isUserAMonkey() {
8912        synchronized (this) {
8913            // If there is a controller also implies the user is a monkey.
8914            return (mUserIsMonkey || mController != null);
8915        }
8916    }
8917
8918    public void requestBugReport() {
8919        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8920        SystemProperties.set("ctl.start", "bugreport");
8921    }
8922
8923    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8924        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8925    }
8926
8927    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8928        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8929            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8930        }
8931        return KEY_DISPATCHING_TIMEOUT;
8932    }
8933
8934    @Override
8935    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8936        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8937                != PackageManager.PERMISSION_GRANTED) {
8938            throw new SecurityException("Requires permission "
8939                    + android.Manifest.permission.FILTER_EVENTS);
8940        }
8941        ProcessRecord proc;
8942        long timeout;
8943        synchronized (this) {
8944            synchronized (mPidsSelfLocked) {
8945                proc = mPidsSelfLocked.get(pid);
8946            }
8947            timeout = getInputDispatchingTimeoutLocked(proc);
8948        }
8949
8950        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8951            return -1;
8952        }
8953
8954        return timeout;
8955    }
8956
8957    /**
8958     * Handle input dispatching timeouts.
8959     * Returns whether input dispatching should be aborted or not.
8960     */
8961    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8962            final ActivityRecord activity, final ActivityRecord parent,
8963            final boolean aboveSystem, String reason) {
8964        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8965                != PackageManager.PERMISSION_GRANTED) {
8966            throw new SecurityException("Requires permission "
8967                    + android.Manifest.permission.FILTER_EVENTS);
8968        }
8969
8970        final String annotation;
8971        if (reason == null) {
8972            annotation = "Input dispatching timed out";
8973        } else {
8974            annotation = "Input dispatching timed out (" + reason + ")";
8975        }
8976
8977        if (proc != null) {
8978            synchronized (this) {
8979                if (proc.debugging) {
8980                    return false;
8981                }
8982
8983                if (mDidDexOpt) {
8984                    // Give more time since we were dexopting.
8985                    mDidDexOpt = false;
8986                    return false;
8987                }
8988
8989                if (proc.instrumentationClass != null) {
8990                    Bundle info = new Bundle();
8991                    info.putString("shortMsg", "keyDispatchingTimedOut");
8992                    info.putString("longMsg", annotation);
8993                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8994                    return true;
8995                }
8996            }
8997            mHandler.post(new Runnable() {
8998                @Override
8999                public void run() {
9000                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9001                }
9002            });
9003        }
9004
9005        return true;
9006    }
9007
9008    public Bundle getAssistContextExtras(int requestType) {
9009        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9010                "getAssistContextExtras()");
9011        PendingAssistExtras pae;
9012        Bundle extras = new Bundle();
9013        synchronized (this) {
9014            ActivityRecord activity = getFocusedStack().mResumedActivity;
9015            if (activity == null) {
9016                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9017                return null;
9018            }
9019            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9020            if (activity.app == null || activity.app.thread == null) {
9021                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9022                return extras;
9023            }
9024            if (activity.app.pid == Binder.getCallingPid()) {
9025                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9026                return extras;
9027            }
9028            pae = new PendingAssistExtras(activity);
9029            try {
9030                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9031                        requestType);
9032                mPendingAssistExtras.add(pae);
9033                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9034            } catch (RemoteException e) {
9035                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9036                return extras;
9037            }
9038        }
9039        synchronized (pae) {
9040            while (!pae.haveResult) {
9041                try {
9042                    pae.wait();
9043                } catch (InterruptedException e) {
9044                }
9045            }
9046            if (pae.result != null) {
9047                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9048            }
9049        }
9050        synchronized (this) {
9051            mPendingAssistExtras.remove(pae);
9052            mHandler.removeCallbacks(pae);
9053        }
9054        return extras;
9055    }
9056
9057    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9058        PendingAssistExtras pae = (PendingAssistExtras)token;
9059        synchronized (pae) {
9060            pae.result = extras;
9061            pae.haveResult = true;
9062            pae.notifyAll();
9063        }
9064    }
9065
9066    public void registerProcessObserver(IProcessObserver observer) {
9067        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9068                "registerProcessObserver()");
9069        synchronized (this) {
9070            mProcessObservers.register(observer);
9071        }
9072    }
9073
9074    @Override
9075    public void unregisterProcessObserver(IProcessObserver observer) {
9076        synchronized (this) {
9077            mProcessObservers.unregister(observer);
9078        }
9079    }
9080
9081    @Override
9082    public boolean convertFromTranslucent(IBinder token) {
9083        final long origId = Binder.clearCallingIdentity();
9084        try {
9085            synchronized (this) {
9086                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9087                if (r == null) {
9088                    return false;
9089                }
9090                if (r.changeWindowTranslucency(true)) {
9091                    mWindowManager.setAppFullscreen(token, true);
9092                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9093                    return true;
9094                }
9095                return false;
9096            }
9097        } finally {
9098            Binder.restoreCallingIdentity(origId);
9099        }
9100    }
9101
9102    @Override
9103    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9104        final long origId = Binder.clearCallingIdentity();
9105        try {
9106            synchronized (this) {
9107                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9108                if (r == null) {
9109                    return false;
9110                }
9111                if (r.changeWindowTranslucency(false)) {
9112                    r.task.stack.convertToTranslucent(r, options);
9113                    mWindowManager.setAppFullscreen(token, false);
9114                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9115                    return true;
9116                }
9117                return false;
9118            }
9119        } finally {
9120            Binder.restoreCallingIdentity(origId);
9121        }
9122    }
9123
9124    @Override
9125    public ActivityOptions getActivityOptions(IBinder token) {
9126        final long origId = Binder.clearCallingIdentity();
9127        try {
9128            synchronized (this) {
9129                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9130                if (r != null) {
9131                    final ActivityOptions activityOptions = r.pendingOptions;
9132                    r.pendingOptions = null;
9133                    return activityOptions;
9134                }
9135                return null;
9136            }
9137        } finally {
9138            Binder.restoreCallingIdentity(origId);
9139        }
9140    }
9141
9142    @Override
9143    public void setImmersive(IBinder token, boolean immersive) {
9144        synchronized(this) {
9145            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9146            if (r == null) {
9147                throw new IllegalArgumentException();
9148            }
9149            r.immersive = immersive;
9150
9151            // update associated state if we're frontmost
9152            if (r == mFocusedActivity) {
9153                if (DEBUG_IMMERSIVE) {
9154                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9155                }
9156                applyUpdateLockStateLocked(r);
9157            }
9158        }
9159    }
9160
9161    @Override
9162    public boolean isImmersive(IBinder token) {
9163        synchronized (this) {
9164            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9165            if (r == null) {
9166                throw new IllegalArgumentException();
9167            }
9168            return r.immersive;
9169        }
9170    }
9171
9172    public boolean isTopActivityImmersive() {
9173        enforceNotIsolatedCaller("startActivity");
9174        synchronized (this) {
9175            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9176            return (r != null) ? r.immersive : false;
9177        }
9178    }
9179
9180    public final void enterSafeMode() {
9181        synchronized(this) {
9182            // It only makes sense to do this before the system is ready
9183            // and started launching other packages.
9184            if (!mSystemReady) {
9185                try {
9186                    AppGlobals.getPackageManager().enterSafeMode();
9187                } catch (RemoteException e) {
9188                }
9189            }
9190
9191            mSafeMode = true;
9192        }
9193    }
9194
9195    public final void showSafeModeOverlay() {
9196        View v = LayoutInflater.from(mContext).inflate(
9197                com.android.internal.R.layout.safe_mode, null);
9198        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9199        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9200        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9201        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9202        lp.gravity = Gravity.BOTTOM | Gravity.START;
9203        lp.format = v.getBackground().getOpacity();
9204        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9205                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9206        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9207        ((WindowManager)mContext.getSystemService(
9208                Context.WINDOW_SERVICE)).addView(v, lp);
9209    }
9210
9211    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9212        if (!(sender instanceof PendingIntentRecord)) {
9213            return;
9214        }
9215        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9216        synchronized (stats) {
9217            if (mBatteryStatsService.isOnBattery()) {
9218                mBatteryStatsService.enforceCallingPermission();
9219                PendingIntentRecord rec = (PendingIntentRecord)sender;
9220                int MY_UID = Binder.getCallingUid();
9221                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9222                BatteryStatsImpl.Uid.Pkg pkg =
9223                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9224                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9225                pkg.incWakeupsLocked();
9226            }
9227        }
9228    }
9229
9230    public boolean killPids(int[] pids, String pReason, boolean secure) {
9231        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9232            throw new SecurityException("killPids only available to the system");
9233        }
9234        String reason = (pReason == null) ? "Unknown" : pReason;
9235        // XXX Note: don't acquire main activity lock here, because the window
9236        // manager calls in with its locks held.
9237
9238        boolean killed = false;
9239        synchronized (mPidsSelfLocked) {
9240            int[] types = new int[pids.length];
9241            int worstType = 0;
9242            for (int i=0; i<pids.length; i++) {
9243                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9244                if (proc != null) {
9245                    int type = proc.setAdj;
9246                    types[i] = type;
9247                    if (type > worstType) {
9248                        worstType = type;
9249                    }
9250                }
9251            }
9252
9253            // If the worst oom_adj is somewhere in the cached proc LRU range,
9254            // then constrain it so we will kill all cached procs.
9255            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9256                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9257                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9258            }
9259
9260            // If this is not a secure call, don't let it kill processes that
9261            // are important.
9262            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9263                worstType = ProcessList.SERVICE_ADJ;
9264            }
9265
9266            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9267            for (int i=0; i<pids.length; i++) {
9268                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9269                if (proc == null) {
9270                    continue;
9271                }
9272                int adj = proc.setAdj;
9273                if (adj >= worstType && !proc.killedByAm) {
9274                    killUnneededProcessLocked(proc, reason);
9275                    killed = true;
9276                }
9277            }
9278        }
9279        return killed;
9280    }
9281
9282    @Override
9283    public void killUid(int uid, String reason) {
9284        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9285            throw new SecurityException("killUid only available to the system");
9286        }
9287        synchronized (this) {
9288            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9289                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9290                    reason != null ? reason : "kill uid");
9291        }
9292    }
9293
9294    @Override
9295    public boolean killProcessesBelowForeground(String reason) {
9296        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9297            throw new SecurityException("killProcessesBelowForeground() only available to system");
9298        }
9299
9300        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9301    }
9302
9303    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9304        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9305            throw new SecurityException("killProcessesBelowAdj() only available to system");
9306        }
9307
9308        boolean killed = false;
9309        synchronized (mPidsSelfLocked) {
9310            final int size = mPidsSelfLocked.size();
9311            for (int i = 0; i < size; i++) {
9312                final int pid = mPidsSelfLocked.keyAt(i);
9313                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9314                if (proc == null) continue;
9315
9316                final int adj = proc.setAdj;
9317                if (adj > belowAdj && !proc.killedByAm) {
9318                    killUnneededProcessLocked(proc, reason);
9319                    killed = true;
9320                }
9321            }
9322        }
9323        return killed;
9324    }
9325
9326    @Override
9327    public void hang(final IBinder who, boolean allowRestart) {
9328        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9329                != PackageManager.PERMISSION_GRANTED) {
9330            throw new SecurityException("Requires permission "
9331                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9332        }
9333
9334        final IBinder.DeathRecipient death = new DeathRecipient() {
9335            @Override
9336            public void binderDied() {
9337                synchronized (this) {
9338                    notifyAll();
9339                }
9340            }
9341        };
9342
9343        try {
9344            who.linkToDeath(death, 0);
9345        } catch (RemoteException e) {
9346            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9347            return;
9348        }
9349
9350        synchronized (this) {
9351            Watchdog.getInstance().setAllowRestart(allowRestart);
9352            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9353            synchronized (death) {
9354                while (who.isBinderAlive()) {
9355                    try {
9356                        death.wait();
9357                    } catch (InterruptedException e) {
9358                    }
9359                }
9360            }
9361            Watchdog.getInstance().setAllowRestart(true);
9362        }
9363    }
9364
9365    @Override
9366    public void restart() {
9367        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9368                != PackageManager.PERMISSION_GRANTED) {
9369            throw new SecurityException("Requires permission "
9370                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9371        }
9372
9373        Log.i(TAG, "Sending shutdown broadcast...");
9374
9375        BroadcastReceiver br = new BroadcastReceiver() {
9376            @Override public void onReceive(Context context, Intent intent) {
9377                // Now the broadcast is done, finish up the low-level shutdown.
9378                Log.i(TAG, "Shutting down activity manager...");
9379                shutdown(10000);
9380                Log.i(TAG, "Shutdown complete, restarting!");
9381                Process.killProcess(Process.myPid());
9382                System.exit(10);
9383            }
9384        };
9385
9386        // First send the high-level shut down broadcast.
9387        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9388        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9389        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9390        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9391        mContext.sendOrderedBroadcastAsUser(intent,
9392                UserHandle.ALL, null, br, mHandler, 0, null, null);
9393        */
9394        br.onReceive(mContext, intent);
9395    }
9396
9397    private long getLowRamTimeSinceIdle(long now) {
9398        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9399    }
9400
9401    @Override
9402    public void performIdleMaintenance() {
9403        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9404                != PackageManager.PERMISSION_GRANTED) {
9405            throw new SecurityException("Requires permission "
9406                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9407        }
9408
9409        synchronized (this) {
9410            final long now = SystemClock.uptimeMillis();
9411            final long timeSinceLastIdle = now - mLastIdleTime;
9412            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9413            mLastIdleTime = now;
9414            mLowRamTimeSinceLastIdle = 0;
9415            if (mLowRamStartTime != 0) {
9416                mLowRamStartTime = now;
9417            }
9418
9419            StringBuilder sb = new StringBuilder(128);
9420            sb.append("Idle maintenance over ");
9421            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9422            sb.append(" low RAM for ");
9423            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9424            Slog.i(TAG, sb.toString());
9425
9426            // If at least 1/3 of our time since the last idle period has been spent
9427            // with RAM low, then we want to kill processes.
9428            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9429
9430            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9431                ProcessRecord proc = mLruProcesses.get(i);
9432                if (proc.notCachedSinceIdle) {
9433                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9434                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9435                        if (doKilling && proc.initialIdlePss != 0
9436                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9437                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9438                                    + " from " + proc.initialIdlePss + ")");
9439                        }
9440                    }
9441                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9442                    proc.notCachedSinceIdle = true;
9443                    proc.initialIdlePss = 0;
9444                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9445                            isSleeping(), now);
9446                }
9447            }
9448
9449            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9450            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9451        }
9452    }
9453
9454    private void retrieveSettings() {
9455        final ContentResolver resolver = mContext.getContentResolver();
9456        String debugApp = Settings.Global.getString(
9457            resolver, Settings.Global.DEBUG_APP);
9458        boolean waitForDebugger = Settings.Global.getInt(
9459            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9460        boolean alwaysFinishActivities = Settings.Global.getInt(
9461            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9462        boolean forceRtl = Settings.Global.getInt(
9463                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9464        // Transfer any global setting for forcing RTL layout, into a System Property
9465        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9466
9467        Configuration configuration = new Configuration();
9468        Settings.System.getConfiguration(resolver, configuration);
9469        if (forceRtl) {
9470            // This will take care of setting the correct layout direction flags
9471            configuration.setLayoutDirection(configuration.locale);
9472        }
9473
9474        synchronized (this) {
9475            mDebugApp = mOrigDebugApp = debugApp;
9476            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9477            mAlwaysFinishActivities = alwaysFinishActivities;
9478            // This happens before any activities are started, so we can
9479            // change mConfiguration in-place.
9480            updateConfigurationLocked(configuration, null, false, true);
9481            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9482        }
9483    }
9484
9485    public boolean testIsSystemReady() {
9486        // no need to synchronize(this) just to read & return the value
9487        return mSystemReady;
9488    }
9489
9490    private static File getCalledPreBootReceiversFile() {
9491        File dataDir = Environment.getDataDirectory();
9492        File systemDir = new File(dataDir, "system");
9493        File fname = new File(systemDir, "called_pre_boots.dat");
9494        return fname;
9495    }
9496
9497    static final int LAST_DONE_VERSION = 10000;
9498
9499    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9500        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9501        File file = getCalledPreBootReceiversFile();
9502        FileInputStream fis = null;
9503        try {
9504            fis = new FileInputStream(file);
9505            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9506            int fvers = dis.readInt();
9507            if (fvers == LAST_DONE_VERSION) {
9508                String vers = dis.readUTF();
9509                String codename = dis.readUTF();
9510                String build = dis.readUTF();
9511                if (android.os.Build.VERSION.RELEASE.equals(vers)
9512                        && android.os.Build.VERSION.CODENAME.equals(codename)
9513                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9514                    int num = dis.readInt();
9515                    while (num > 0) {
9516                        num--;
9517                        String pkg = dis.readUTF();
9518                        String cls = dis.readUTF();
9519                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9520                    }
9521                }
9522            }
9523        } catch (FileNotFoundException e) {
9524        } catch (IOException e) {
9525            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9526        } finally {
9527            if (fis != null) {
9528                try {
9529                    fis.close();
9530                } catch (IOException e) {
9531                }
9532            }
9533        }
9534        return lastDoneReceivers;
9535    }
9536
9537    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9538        File file = getCalledPreBootReceiversFile();
9539        FileOutputStream fos = null;
9540        DataOutputStream dos = null;
9541        try {
9542            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9543            fos = new FileOutputStream(file);
9544            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9545            dos.writeInt(LAST_DONE_VERSION);
9546            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9547            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9548            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9549            dos.writeInt(list.size());
9550            for (int i=0; i<list.size(); i++) {
9551                dos.writeUTF(list.get(i).getPackageName());
9552                dos.writeUTF(list.get(i).getClassName());
9553            }
9554        } catch (IOException e) {
9555            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9556            file.delete();
9557        } finally {
9558            FileUtils.sync(fos);
9559            if (dos != null) {
9560                try {
9561                    dos.close();
9562                } catch (IOException e) {
9563                    // TODO Auto-generated catch block
9564                    e.printStackTrace();
9565                }
9566            }
9567        }
9568    }
9569
9570    public void systemReady(final Runnable goingCallback) {
9571        synchronized(this) {
9572            if (mSystemReady) {
9573                if (goingCallback != null) goingCallback.run();
9574                return;
9575            }
9576
9577            if (mRecentTasks == null) {
9578                mRecentTasks = mTaskPersister.restoreTasksLocked();
9579                if (!mRecentTasks.isEmpty()) {
9580                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9581                }
9582                mTaskPersister.startPersisting();
9583            }
9584
9585            // Check to see if there are any update receivers to run.
9586            if (!mDidUpdate) {
9587                if (mWaitingUpdate) {
9588                    return;
9589                }
9590                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9591                List<ResolveInfo> ris = null;
9592                try {
9593                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9594                            intent, null, 0, 0);
9595                } catch (RemoteException e) {
9596                }
9597                if (ris != null) {
9598                    for (int i=ris.size()-1; i>=0; i--) {
9599                        if ((ris.get(i).activityInfo.applicationInfo.flags
9600                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9601                            ris.remove(i);
9602                        }
9603                    }
9604                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9605
9606                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9607
9608                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
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                        if (lastDoneReceivers.contains(comp)) {
9613                            // We already did the pre boot receiver for this app with the current
9614                            // platform version, so don't do it again...
9615                            ris.remove(i);
9616                            i--;
9617                            // ...however, do keep it as one that has been done, so we don't
9618                            // forget about it when rewriting the file of last done receivers.
9619                            doneReceivers.add(comp);
9620                        }
9621                    }
9622
9623                    final int[] users = getUsersLocked();
9624                    for (int i=0; i<ris.size(); i++) {
9625                        ActivityInfo ai = ris.get(i).activityInfo;
9626                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9627                        doneReceivers.add(comp);
9628                        intent.setComponent(comp);
9629                        for (int j=0; j<users.length; j++) {
9630                            IIntentReceiver finisher = null;
9631                            if (i == ris.size()-1 && j == users.length-1) {
9632                                finisher = new IIntentReceiver.Stub() {
9633                                    public void performReceive(Intent intent, int resultCode,
9634                                            String data, Bundle extras, boolean ordered,
9635                                            boolean sticky, int sendingUser) {
9636                                        // The raw IIntentReceiver interface is called
9637                                        // with the AM lock held, so redispatch to
9638                                        // execute our code without the lock.
9639                                        mHandler.post(new Runnable() {
9640                                            public void run() {
9641                                                synchronized (ActivityManagerService.this) {
9642                                                    mDidUpdate = true;
9643                                                }
9644                                                writeLastDonePreBootReceivers(doneReceivers);
9645                                                showBootMessage(mContext.getText(
9646                                                        R.string.android_upgrading_complete),
9647                                                        false);
9648                                                systemReady(goingCallback);
9649                                            }
9650                                        });
9651                                    }
9652                                };
9653                            }
9654                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9655                                    + " for user " + users[j]);
9656                            broadcastIntentLocked(null, null, intent, null, finisher,
9657                                    0, null, null, null, AppOpsManager.OP_NONE,
9658                                    true, false, MY_PID, Process.SYSTEM_UID,
9659                                    users[j]);
9660                            if (finisher != null) {
9661                                mWaitingUpdate = true;
9662                            }
9663                        }
9664                    }
9665                }
9666                if (mWaitingUpdate) {
9667                    return;
9668                }
9669                mDidUpdate = true;
9670            }
9671
9672            mAppOpsService.systemReady();
9673            mUsageStatsService.systemReady();
9674            mSystemReady = true;
9675        }
9676
9677        ArrayList<ProcessRecord> procsToKill = null;
9678        synchronized(mPidsSelfLocked) {
9679            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9680                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9681                if (!isAllowedWhileBooting(proc.info)){
9682                    if (procsToKill == null) {
9683                        procsToKill = new ArrayList<ProcessRecord>();
9684                    }
9685                    procsToKill.add(proc);
9686                }
9687            }
9688        }
9689
9690        synchronized(this) {
9691            if (procsToKill != null) {
9692                for (int i=procsToKill.size()-1; i>=0; i--) {
9693                    ProcessRecord proc = procsToKill.get(i);
9694                    Slog.i(TAG, "Removing system update proc: " + proc);
9695                    removeProcessLocked(proc, true, false, "system update done");
9696                }
9697            }
9698
9699            // Now that we have cleaned up any update processes, we
9700            // are ready to start launching real processes and know that
9701            // we won't trample on them any more.
9702            mProcessesReady = true;
9703        }
9704
9705        Slog.i(TAG, "System now ready");
9706        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9707            SystemClock.uptimeMillis());
9708
9709        synchronized(this) {
9710            // Make sure we have no pre-ready processes sitting around.
9711
9712            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9713                ResolveInfo ri = mContext.getPackageManager()
9714                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9715                                STOCK_PM_FLAGS);
9716                CharSequence errorMsg = null;
9717                if (ri != null) {
9718                    ActivityInfo ai = ri.activityInfo;
9719                    ApplicationInfo app = ai.applicationInfo;
9720                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9721                        mTopAction = Intent.ACTION_FACTORY_TEST;
9722                        mTopData = null;
9723                        mTopComponent = new ComponentName(app.packageName,
9724                                ai.name);
9725                    } else {
9726                        errorMsg = mContext.getResources().getText(
9727                                com.android.internal.R.string.factorytest_not_system);
9728                    }
9729                } else {
9730                    errorMsg = mContext.getResources().getText(
9731                            com.android.internal.R.string.factorytest_no_action);
9732                }
9733                if (errorMsg != null) {
9734                    mTopAction = null;
9735                    mTopData = null;
9736                    mTopComponent = null;
9737                    Message msg = Message.obtain();
9738                    msg.what = SHOW_FACTORY_ERROR_MSG;
9739                    msg.getData().putCharSequence("msg", errorMsg);
9740                    mHandler.sendMessage(msg);
9741                }
9742            }
9743        }
9744
9745        retrieveSettings();
9746
9747        synchronized (this) {
9748            readGrantedUriPermissionsLocked();
9749        }
9750
9751        if (goingCallback != null) goingCallback.run();
9752
9753        mSystemServiceManager.startUser(mCurrentUserId);
9754
9755        synchronized (this) {
9756            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9757                try {
9758                    List apps = AppGlobals.getPackageManager().
9759                        getPersistentApplications(STOCK_PM_FLAGS);
9760                    if (apps != null) {
9761                        int N = apps.size();
9762                        int i;
9763                        for (i=0; i<N; i++) {
9764                            ApplicationInfo info
9765                                = (ApplicationInfo)apps.get(i);
9766                            if (info != null &&
9767                                    !info.packageName.equals("android")) {
9768                                addAppLocked(info, false);
9769                            }
9770                        }
9771                    }
9772                } catch (RemoteException ex) {
9773                    // pm is in same process, this will never happen.
9774                }
9775            }
9776
9777            // Start up initial activity.
9778            mBooting = true;
9779
9780            try {
9781                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9782                    Message msg = Message.obtain();
9783                    msg.what = SHOW_UID_ERROR_MSG;
9784                    mHandler.sendMessage(msg);
9785                }
9786            } catch (RemoteException e) {
9787            }
9788
9789            long ident = Binder.clearCallingIdentity();
9790            try {
9791                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9792                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9793                        | Intent.FLAG_RECEIVER_FOREGROUND);
9794                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9795                broadcastIntentLocked(null, null, intent,
9796                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9797                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9798                intent = new Intent(Intent.ACTION_USER_STARTING);
9799                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9800                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9801                broadcastIntentLocked(null, null, intent,
9802                        null, new IIntentReceiver.Stub() {
9803                            @Override
9804                            public void performReceive(Intent intent, int resultCode, String data,
9805                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9806                                    throws RemoteException {
9807                            }
9808                        }, 0, null, null,
9809                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9810                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9811            } catch (Throwable t) {
9812                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9813            } finally {
9814                Binder.restoreCallingIdentity(ident);
9815            }
9816            mStackSupervisor.resumeTopActivitiesLocked();
9817            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9818        }
9819    }
9820
9821    private boolean makeAppCrashingLocked(ProcessRecord app,
9822            String shortMsg, String longMsg, String stackTrace) {
9823        app.crashing = true;
9824        app.crashingReport = generateProcessError(app,
9825                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9826        startAppProblemLocked(app);
9827        app.stopFreezingAllLocked();
9828        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9829    }
9830
9831    private void makeAppNotRespondingLocked(ProcessRecord app,
9832            String activity, String shortMsg, String longMsg) {
9833        app.notResponding = true;
9834        app.notRespondingReport = generateProcessError(app,
9835                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9836                activity, shortMsg, longMsg, null);
9837        startAppProblemLocked(app);
9838        app.stopFreezingAllLocked();
9839    }
9840
9841    /**
9842     * Generate a process error record, suitable for attachment to a ProcessRecord.
9843     *
9844     * @param app The ProcessRecord in which the error occurred.
9845     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9846     *                      ActivityManager.AppErrorStateInfo
9847     * @param activity The activity associated with the crash, if known.
9848     * @param shortMsg Short message describing the crash.
9849     * @param longMsg Long message describing the crash.
9850     * @param stackTrace Full crash stack trace, may be null.
9851     *
9852     * @return Returns a fully-formed AppErrorStateInfo record.
9853     */
9854    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9855            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9856        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9857
9858        report.condition = condition;
9859        report.processName = app.processName;
9860        report.pid = app.pid;
9861        report.uid = app.info.uid;
9862        report.tag = activity;
9863        report.shortMsg = shortMsg;
9864        report.longMsg = longMsg;
9865        report.stackTrace = stackTrace;
9866
9867        return report;
9868    }
9869
9870    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9871        synchronized (this) {
9872            app.crashing = false;
9873            app.crashingReport = null;
9874            app.notResponding = false;
9875            app.notRespondingReport = null;
9876            if (app.anrDialog == fromDialog) {
9877                app.anrDialog = null;
9878            }
9879            if (app.waitDialog == fromDialog) {
9880                app.waitDialog = null;
9881            }
9882            if (app.pid > 0 && app.pid != MY_PID) {
9883                handleAppCrashLocked(app, null, null, null);
9884                killUnneededProcessLocked(app, "user request after error");
9885            }
9886        }
9887    }
9888
9889    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9890            String stackTrace) {
9891        long now = SystemClock.uptimeMillis();
9892
9893        Long crashTime;
9894        if (!app.isolated) {
9895            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9896        } else {
9897            crashTime = null;
9898        }
9899        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9900            // This process loses!
9901            Slog.w(TAG, "Process " + app.info.processName
9902                    + " has crashed too many times: killing!");
9903            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9904                    app.userId, app.info.processName, app.uid);
9905            mStackSupervisor.handleAppCrashLocked(app);
9906            if (!app.persistent) {
9907                // We don't want to start this process again until the user
9908                // explicitly does so...  but for persistent process, we really
9909                // need to keep it running.  If a persistent process is actually
9910                // repeatedly crashing, then badness for everyone.
9911                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9912                        app.info.processName);
9913                if (!app.isolated) {
9914                    // XXX We don't have a way to mark isolated processes
9915                    // as bad, since they don't have a peristent identity.
9916                    mBadProcesses.put(app.info.processName, app.uid,
9917                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9918                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9919                }
9920                app.bad = true;
9921                app.removed = true;
9922                // Don't let services in this process be restarted and potentially
9923                // annoy the user repeatedly.  Unless it is persistent, since those
9924                // processes run critical code.
9925                removeProcessLocked(app, false, false, "crash");
9926                mStackSupervisor.resumeTopActivitiesLocked();
9927                return false;
9928            }
9929            mStackSupervisor.resumeTopActivitiesLocked();
9930        } else {
9931            mStackSupervisor.finishTopRunningActivityLocked(app);
9932        }
9933
9934        // Bump up the crash count of any services currently running in the proc.
9935        for (int i=app.services.size()-1; i>=0; i--) {
9936            // Any services running in the application need to be placed
9937            // back in the pending list.
9938            ServiceRecord sr = app.services.valueAt(i);
9939            sr.crashCount++;
9940        }
9941
9942        // If the crashing process is what we consider to be the "home process" and it has been
9943        // replaced by a third-party app, clear the package preferred activities from packages
9944        // with a home activity running in the process to prevent a repeatedly crashing app
9945        // from blocking the user to manually clear the list.
9946        final ArrayList<ActivityRecord> activities = app.activities;
9947        if (app == mHomeProcess && activities.size() > 0
9948                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9949            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9950                final ActivityRecord r = activities.get(activityNdx);
9951                if (r.isHomeActivity()) {
9952                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9953                    try {
9954                        ActivityThread.getPackageManager()
9955                                .clearPackagePreferredActivities(r.packageName);
9956                    } catch (RemoteException c) {
9957                        // pm is in same process, this will never happen.
9958                    }
9959                }
9960            }
9961        }
9962
9963        if (!app.isolated) {
9964            // XXX Can't keep track of crash times for isolated processes,
9965            // because they don't have a perisistent identity.
9966            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9967        }
9968
9969        return true;
9970    }
9971
9972    void startAppProblemLocked(ProcessRecord app) {
9973        if (app.userId == mCurrentUserId) {
9974            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9975                    mContext, app.info.packageName, app.info.flags);
9976        } else {
9977            // If this app is not running under the current user, then we
9978            // can't give it a report button because that would require
9979            // launching the report UI under a different user.
9980            app.errorReportReceiver = null;
9981        }
9982        skipCurrentReceiverLocked(app);
9983    }
9984
9985    void skipCurrentReceiverLocked(ProcessRecord app) {
9986        for (BroadcastQueue queue : mBroadcastQueues) {
9987            queue.skipCurrentReceiverLocked(app);
9988        }
9989    }
9990
9991    /**
9992     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9993     * The application process will exit immediately after this call returns.
9994     * @param app object of the crashing app, null for the system server
9995     * @param crashInfo describing the exception
9996     */
9997    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9998        ProcessRecord r = findAppProcess(app, "Crash");
9999        final String processName = app == null ? "system_server"
10000                : (r == null ? "unknown" : r.processName);
10001
10002        handleApplicationCrashInner("crash", r, processName, crashInfo);
10003    }
10004
10005    /* Native crash reporting uses this inner version because it needs to be somewhat
10006     * decoupled from the AM-managed cleanup lifecycle
10007     */
10008    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10009            ApplicationErrorReport.CrashInfo crashInfo) {
10010        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10011                UserHandle.getUserId(Binder.getCallingUid()), processName,
10012                r == null ? -1 : r.info.flags,
10013                crashInfo.exceptionClassName,
10014                crashInfo.exceptionMessage,
10015                crashInfo.throwFileName,
10016                crashInfo.throwLineNumber);
10017
10018        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10019
10020        crashApplication(r, crashInfo);
10021    }
10022
10023    public void handleApplicationStrictModeViolation(
10024            IBinder app,
10025            int violationMask,
10026            StrictMode.ViolationInfo info) {
10027        ProcessRecord r = findAppProcess(app, "StrictMode");
10028        if (r == null) {
10029            return;
10030        }
10031
10032        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10033            Integer stackFingerprint = info.hashCode();
10034            boolean logIt = true;
10035            synchronized (mAlreadyLoggedViolatedStacks) {
10036                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10037                    logIt = false;
10038                    // TODO: sub-sample into EventLog for these, with
10039                    // the info.durationMillis?  Then we'd get
10040                    // the relative pain numbers, without logging all
10041                    // the stack traces repeatedly.  We'd want to do
10042                    // likewise in the client code, which also does
10043                    // dup suppression, before the Binder call.
10044                } else {
10045                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10046                        mAlreadyLoggedViolatedStacks.clear();
10047                    }
10048                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10049                }
10050            }
10051            if (logIt) {
10052                logStrictModeViolationToDropBox(r, info);
10053            }
10054        }
10055
10056        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10057            AppErrorResult result = new AppErrorResult();
10058            synchronized (this) {
10059                final long origId = Binder.clearCallingIdentity();
10060
10061                Message msg = Message.obtain();
10062                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10063                HashMap<String, Object> data = new HashMap<String, Object>();
10064                data.put("result", result);
10065                data.put("app", r);
10066                data.put("violationMask", violationMask);
10067                data.put("info", info);
10068                msg.obj = data;
10069                mHandler.sendMessage(msg);
10070
10071                Binder.restoreCallingIdentity(origId);
10072            }
10073            int res = result.get();
10074            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10075        }
10076    }
10077
10078    // Depending on the policy in effect, there could be a bunch of
10079    // these in quick succession so we try to batch these together to
10080    // minimize disk writes, number of dropbox entries, and maximize
10081    // compression, by having more fewer, larger records.
10082    private void logStrictModeViolationToDropBox(
10083            ProcessRecord process,
10084            StrictMode.ViolationInfo info) {
10085        if (info == null) {
10086            return;
10087        }
10088        final boolean isSystemApp = process == null ||
10089                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10090                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10091        final String processName = process == null ? "unknown" : process.processName;
10092        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10093        final DropBoxManager dbox = (DropBoxManager)
10094                mContext.getSystemService(Context.DROPBOX_SERVICE);
10095
10096        // Exit early if the dropbox isn't configured to accept this report type.
10097        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10098
10099        boolean bufferWasEmpty;
10100        boolean needsFlush;
10101        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10102        synchronized (sb) {
10103            bufferWasEmpty = sb.length() == 0;
10104            appendDropBoxProcessHeaders(process, processName, sb);
10105            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10106            sb.append("System-App: ").append(isSystemApp).append("\n");
10107            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10108            if (info.violationNumThisLoop != 0) {
10109                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10110            }
10111            if (info.numAnimationsRunning != 0) {
10112                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10113            }
10114            if (info.broadcastIntentAction != null) {
10115                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10116            }
10117            if (info.durationMillis != -1) {
10118                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10119            }
10120            if (info.numInstances != -1) {
10121                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10122            }
10123            if (info.tags != null) {
10124                for (String tag : info.tags) {
10125                    sb.append("Span-Tag: ").append(tag).append("\n");
10126                }
10127            }
10128            sb.append("\n");
10129            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10130                sb.append(info.crashInfo.stackTrace);
10131            }
10132            sb.append("\n");
10133
10134            // Only buffer up to ~64k.  Various logging bits truncate
10135            // things at 128k.
10136            needsFlush = (sb.length() > 64 * 1024);
10137        }
10138
10139        // Flush immediately if the buffer's grown too large, or this
10140        // is a non-system app.  Non-system apps are isolated with a
10141        // different tag & policy and not batched.
10142        //
10143        // Batching is useful during internal testing with
10144        // StrictMode settings turned up high.  Without batching,
10145        // thousands of separate files could be created on boot.
10146        if (!isSystemApp || needsFlush) {
10147            new Thread("Error dump: " + dropboxTag) {
10148                @Override
10149                public void run() {
10150                    String report;
10151                    synchronized (sb) {
10152                        report = sb.toString();
10153                        sb.delete(0, sb.length());
10154                        sb.trimToSize();
10155                    }
10156                    if (report.length() != 0) {
10157                        dbox.addText(dropboxTag, report);
10158                    }
10159                }
10160            }.start();
10161            return;
10162        }
10163
10164        // System app batching:
10165        if (!bufferWasEmpty) {
10166            // An existing dropbox-writing thread is outstanding, so
10167            // we don't need to start it up.  The existing thread will
10168            // catch the buffer appends we just did.
10169            return;
10170        }
10171
10172        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10173        // (After this point, we shouldn't access AMS internal data structures.)
10174        new Thread("Error dump: " + dropboxTag) {
10175            @Override
10176            public void run() {
10177                // 5 second sleep to let stacks arrive and be batched together
10178                try {
10179                    Thread.sleep(5000);  // 5 seconds
10180                } catch (InterruptedException e) {}
10181
10182                String errorReport;
10183                synchronized (mStrictModeBuffer) {
10184                    errorReport = mStrictModeBuffer.toString();
10185                    if (errorReport.length() == 0) {
10186                        return;
10187                    }
10188                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10189                    mStrictModeBuffer.trimToSize();
10190                }
10191                dbox.addText(dropboxTag, errorReport);
10192            }
10193        }.start();
10194    }
10195
10196    /**
10197     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10198     * @param app object of the crashing app, null for the system server
10199     * @param tag reported by the caller
10200     * @param crashInfo describing the context of the error
10201     * @return true if the process should exit immediately (WTF is fatal)
10202     */
10203    public boolean handleApplicationWtf(IBinder app, String tag,
10204            ApplicationErrorReport.CrashInfo crashInfo) {
10205        ProcessRecord r = findAppProcess(app, "WTF");
10206        final String processName = app == null ? "system_server"
10207                : (r == null ? "unknown" : r.processName);
10208
10209        EventLog.writeEvent(EventLogTags.AM_WTF,
10210                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10211                processName,
10212                r == null ? -1 : r.info.flags,
10213                tag, crashInfo.exceptionMessage);
10214
10215        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10216
10217        if (r != null && r.pid != Process.myPid() &&
10218                Settings.Global.getInt(mContext.getContentResolver(),
10219                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10220            crashApplication(r, crashInfo);
10221            return true;
10222        } else {
10223            return false;
10224        }
10225    }
10226
10227    /**
10228     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10229     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10230     */
10231    private ProcessRecord findAppProcess(IBinder app, String reason) {
10232        if (app == null) {
10233            return null;
10234        }
10235
10236        synchronized (this) {
10237            final int NP = mProcessNames.getMap().size();
10238            for (int ip=0; ip<NP; ip++) {
10239                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10240                final int NA = apps.size();
10241                for (int ia=0; ia<NA; ia++) {
10242                    ProcessRecord p = apps.valueAt(ia);
10243                    if (p.thread != null && p.thread.asBinder() == app) {
10244                        return p;
10245                    }
10246                }
10247            }
10248
10249            Slog.w(TAG, "Can't find mystery application for " + reason
10250                    + " from pid=" + Binder.getCallingPid()
10251                    + " uid=" + Binder.getCallingUid() + ": " + app);
10252            return null;
10253        }
10254    }
10255
10256    /**
10257     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10258     * to append various headers to the dropbox log text.
10259     */
10260    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10261            StringBuilder sb) {
10262        // Watchdog thread ends up invoking this function (with
10263        // a null ProcessRecord) to add the stack file to dropbox.
10264        // Do not acquire a lock on this (am) in such cases, as it
10265        // could cause a potential deadlock, if and when watchdog
10266        // is invoked due to unavailability of lock on am and it
10267        // would prevent watchdog from killing system_server.
10268        if (process == null) {
10269            sb.append("Process: ").append(processName).append("\n");
10270            return;
10271        }
10272        // Note: ProcessRecord 'process' is guarded by the service
10273        // instance.  (notably process.pkgList, which could otherwise change
10274        // concurrently during execution of this method)
10275        synchronized (this) {
10276            sb.append("Process: ").append(processName).append("\n");
10277            int flags = process.info.flags;
10278            IPackageManager pm = AppGlobals.getPackageManager();
10279            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10280            for (int ip=0; ip<process.pkgList.size(); ip++) {
10281                String pkg = process.pkgList.keyAt(ip);
10282                sb.append("Package: ").append(pkg);
10283                try {
10284                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10285                    if (pi != null) {
10286                        sb.append(" v").append(pi.versionCode);
10287                        if (pi.versionName != null) {
10288                            sb.append(" (").append(pi.versionName).append(")");
10289                        }
10290                    }
10291                } catch (RemoteException e) {
10292                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10293                }
10294                sb.append("\n");
10295            }
10296        }
10297    }
10298
10299    private static String processClass(ProcessRecord process) {
10300        if (process == null || process.pid == MY_PID) {
10301            return "system_server";
10302        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10303            return "system_app";
10304        } else {
10305            return "data_app";
10306        }
10307    }
10308
10309    /**
10310     * Write a description of an error (crash, WTF, ANR) to the drop box.
10311     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10312     * @param process which caused the error, null means the system server
10313     * @param activity which triggered the error, null if unknown
10314     * @param parent activity related to the error, null if unknown
10315     * @param subject line related to the error, null if absent
10316     * @param report in long form describing the error, null if absent
10317     * @param logFile to include in the report, null if none
10318     * @param crashInfo giving an application stack trace, null if absent
10319     */
10320    public void addErrorToDropBox(String eventType,
10321            ProcessRecord process, String processName, ActivityRecord activity,
10322            ActivityRecord parent, String subject,
10323            final String report, final File logFile,
10324            final ApplicationErrorReport.CrashInfo crashInfo) {
10325        // NOTE -- this must never acquire the ActivityManagerService lock,
10326        // otherwise the watchdog may be prevented from resetting the system.
10327
10328        final String dropboxTag = processClass(process) + "_" + eventType;
10329        final DropBoxManager dbox = (DropBoxManager)
10330                mContext.getSystemService(Context.DROPBOX_SERVICE);
10331
10332        // Exit early if the dropbox isn't configured to accept this report type.
10333        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10334
10335        final StringBuilder sb = new StringBuilder(1024);
10336        appendDropBoxProcessHeaders(process, processName, sb);
10337        if (activity != null) {
10338            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10339        }
10340        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10341            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10342        }
10343        if (parent != null && parent != activity) {
10344            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10345        }
10346        if (subject != null) {
10347            sb.append("Subject: ").append(subject).append("\n");
10348        }
10349        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10350        if (Debug.isDebuggerConnected()) {
10351            sb.append("Debugger: Connected\n");
10352        }
10353        sb.append("\n");
10354
10355        // Do the rest in a worker thread to avoid blocking the caller on I/O
10356        // (After this point, we shouldn't access AMS internal data structures.)
10357        Thread worker = new Thread("Error dump: " + dropboxTag) {
10358            @Override
10359            public void run() {
10360                if (report != null) {
10361                    sb.append(report);
10362                }
10363                if (logFile != null) {
10364                    try {
10365                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10366                                    "\n\n[[TRUNCATED]]"));
10367                    } catch (IOException e) {
10368                        Slog.e(TAG, "Error reading " + logFile, e);
10369                    }
10370                }
10371                if (crashInfo != null && crashInfo.stackTrace != null) {
10372                    sb.append(crashInfo.stackTrace);
10373                }
10374
10375                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10376                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10377                if (lines > 0) {
10378                    sb.append("\n");
10379
10380                    // Merge several logcat streams, and take the last N lines
10381                    InputStreamReader input = null;
10382                    try {
10383                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10384                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10385                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10386
10387                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10388                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10389                        input = new InputStreamReader(logcat.getInputStream());
10390
10391                        int num;
10392                        char[] buf = new char[8192];
10393                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10394                    } catch (IOException e) {
10395                        Slog.e(TAG, "Error running logcat", e);
10396                    } finally {
10397                        if (input != null) try { input.close(); } catch (IOException e) {}
10398                    }
10399                }
10400
10401                dbox.addText(dropboxTag, sb.toString());
10402            }
10403        };
10404
10405        if (process == null) {
10406            // If process is null, we are being called from some internal code
10407            // and may be about to die -- run this synchronously.
10408            worker.run();
10409        } else {
10410            worker.start();
10411        }
10412    }
10413
10414    /**
10415     * Bring up the "unexpected error" dialog box for a crashing app.
10416     * Deal with edge cases (intercepts from instrumented applications,
10417     * ActivityController, error intent receivers, that sort of thing).
10418     * @param r the application crashing
10419     * @param crashInfo describing the failure
10420     */
10421    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10422        long timeMillis = System.currentTimeMillis();
10423        String shortMsg = crashInfo.exceptionClassName;
10424        String longMsg = crashInfo.exceptionMessage;
10425        String stackTrace = crashInfo.stackTrace;
10426        if (shortMsg != null && longMsg != null) {
10427            longMsg = shortMsg + ": " + longMsg;
10428        } else if (shortMsg != null) {
10429            longMsg = shortMsg;
10430        }
10431
10432        AppErrorResult result = new AppErrorResult();
10433        synchronized (this) {
10434            if (mController != null) {
10435                try {
10436                    String name = r != null ? r.processName : null;
10437                    int pid = r != null ? r.pid : Binder.getCallingPid();
10438                    if (!mController.appCrashed(name, pid,
10439                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10440                        Slog.w(TAG, "Force-killing crashed app " + name
10441                                + " at watcher's request");
10442                        Process.killProcess(pid);
10443                        return;
10444                    }
10445                } catch (RemoteException e) {
10446                    mController = null;
10447                    Watchdog.getInstance().setActivityController(null);
10448                }
10449            }
10450
10451            final long origId = Binder.clearCallingIdentity();
10452
10453            // If this process is running instrumentation, finish it.
10454            if (r != null && r.instrumentationClass != null) {
10455                Slog.w(TAG, "Error in app " + r.processName
10456                      + " running instrumentation " + r.instrumentationClass + ":");
10457                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10458                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10459                Bundle info = new Bundle();
10460                info.putString("shortMsg", shortMsg);
10461                info.putString("longMsg", longMsg);
10462                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10463                Binder.restoreCallingIdentity(origId);
10464                return;
10465            }
10466
10467            // If we can't identify the process or it's already exceeded its crash quota,
10468            // quit right away without showing a crash dialog.
10469            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10470                Binder.restoreCallingIdentity(origId);
10471                return;
10472            }
10473
10474            Message msg = Message.obtain();
10475            msg.what = SHOW_ERROR_MSG;
10476            HashMap data = new HashMap();
10477            data.put("result", result);
10478            data.put("app", r);
10479            msg.obj = data;
10480            mHandler.sendMessage(msg);
10481
10482            Binder.restoreCallingIdentity(origId);
10483        }
10484
10485        int res = result.get();
10486
10487        Intent appErrorIntent = null;
10488        synchronized (this) {
10489            if (r != null && !r.isolated) {
10490                // XXX Can't keep track of crash time for isolated processes,
10491                // since they don't have a persistent identity.
10492                mProcessCrashTimes.put(r.info.processName, r.uid,
10493                        SystemClock.uptimeMillis());
10494            }
10495            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10496                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10497            }
10498        }
10499
10500        if (appErrorIntent != null) {
10501            try {
10502                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10503            } catch (ActivityNotFoundException e) {
10504                Slog.w(TAG, "bug report receiver dissappeared", e);
10505            }
10506        }
10507    }
10508
10509    Intent createAppErrorIntentLocked(ProcessRecord r,
10510            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10511        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10512        if (report == null) {
10513            return null;
10514        }
10515        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10516        result.setComponent(r.errorReportReceiver);
10517        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10518        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10519        return result;
10520    }
10521
10522    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10523            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10524        if (r.errorReportReceiver == null) {
10525            return null;
10526        }
10527
10528        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10529            return null;
10530        }
10531
10532        ApplicationErrorReport report = new ApplicationErrorReport();
10533        report.packageName = r.info.packageName;
10534        report.installerPackageName = r.errorReportReceiver.getPackageName();
10535        report.processName = r.processName;
10536        report.time = timeMillis;
10537        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10538
10539        if (r.crashing || r.forceCrashReport) {
10540            report.type = ApplicationErrorReport.TYPE_CRASH;
10541            report.crashInfo = crashInfo;
10542        } else if (r.notResponding) {
10543            report.type = ApplicationErrorReport.TYPE_ANR;
10544            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10545
10546            report.anrInfo.activity = r.notRespondingReport.tag;
10547            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10548            report.anrInfo.info = r.notRespondingReport.longMsg;
10549        }
10550
10551        return report;
10552    }
10553
10554    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10555        enforceNotIsolatedCaller("getProcessesInErrorState");
10556        // assume our apps are happy - lazy create the list
10557        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10558
10559        final boolean allUsers = ActivityManager.checkUidPermission(
10560                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10561                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10562        int userId = UserHandle.getUserId(Binder.getCallingUid());
10563
10564        synchronized (this) {
10565
10566            // iterate across all processes
10567            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10568                ProcessRecord app = mLruProcesses.get(i);
10569                if (!allUsers && app.userId != userId) {
10570                    continue;
10571                }
10572                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10573                    // This one's in trouble, so we'll generate a report for it
10574                    // crashes are higher priority (in case there's a crash *and* an anr)
10575                    ActivityManager.ProcessErrorStateInfo report = null;
10576                    if (app.crashing) {
10577                        report = app.crashingReport;
10578                    } else if (app.notResponding) {
10579                        report = app.notRespondingReport;
10580                    }
10581
10582                    if (report != null) {
10583                        if (errList == null) {
10584                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10585                        }
10586                        errList.add(report);
10587                    } else {
10588                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10589                                " crashing = " + app.crashing +
10590                                " notResponding = " + app.notResponding);
10591                    }
10592                }
10593            }
10594        }
10595
10596        return errList;
10597    }
10598
10599    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10600        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10601            if (currApp != null) {
10602                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10603            }
10604            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10605        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10606            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10607        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10608            if (currApp != null) {
10609                currApp.lru = 0;
10610            }
10611            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10612        } else if (adj >= ProcessList.SERVICE_ADJ) {
10613            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10614        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10615            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10616        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10617            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10618        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10619            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10620        } else {
10621            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10622        }
10623    }
10624
10625    private void fillInProcMemInfo(ProcessRecord app,
10626            ActivityManager.RunningAppProcessInfo outInfo) {
10627        outInfo.pid = app.pid;
10628        outInfo.uid = app.info.uid;
10629        if (mHeavyWeightProcess == app) {
10630            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10631        }
10632        if (app.persistent) {
10633            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10634        }
10635        if (app.activities.size() > 0) {
10636            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10637        }
10638        outInfo.lastTrimLevel = app.trimMemoryLevel;
10639        int adj = app.curAdj;
10640        outInfo.importance = oomAdjToImportance(adj, outInfo);
10641        outInfo.importanceReasonCode = app.adjTypeCode;
10642        outInfo.processState = app.curProcState;
10643    }
10644
10645    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10646        enforceNotIsolatedCaller("getRunningAppProcesses");
10647        // Lazy instantiation of list
10648        List<ActivityManager.RunningAppProcessInfo> runList = null;
10649        final boolean allUsers = ActivityManager.checkUidPermission(
10650                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10651                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10652        int userId = UserHandle.getUserId(Binder.getCallingUid());
10653        synchronized (this) {
10654            // Iterate across all processes
10655            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10656                ProcessRecord app = mLruProcesses.get(i);
10657                if (!allUsers && app.userId != userId) {
10658                    continue;
10659                }
10660                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10661                    // Generate process state info for running application
10662                    ActivityManager.RunningAppProcessInfo currApp =
10663                        new ActivityManager.RunningAppProcessInfo(app.processName,
10664                                app.pid, app.getPackageList());
10665                    fillInProcMemInfo(app, currApp);
10666                    if (app.adjSource instanceof ProcessRecord) {
10667                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10668                        currApp.importanceReasonImportance = oomAdjToImportance(
10669                                app.adjSourceOom, null);
10670                    } else if (app.adjSource instanceof ActivityRecord) {
10671                        ActivityRecord r = (ActivityRecord)app.adjSource;
10672                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10673                    }
10674                    if (app.adjTarget instanceof ComponentName) {
10675                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10676                    }
10677                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10678                    //        + " lru=" + currApp.lru);
10679                    if (runList == null) {
10680                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10681                    }
10682                    runList.add(currApp);
10683                }
10684            }
10685        }
10686        return runList;
10687    }
10688
10689    public List<ApplicationInfo> getRunningExternalApplications() {
10690        enforceNotIsolatedCaller("getRunningExternalApplications");
10691        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10692        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10693        if (runningApps != null && runningApps.size() > 0) {
10694            Set<String> extList = new HashSet<String>();
10695            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10696                if (app.pkgList != null) {
10697                    for (String pkg : app.pkgList) {
10698                        extList.add(pkg);
10699                    }
10700                }
10701            }
10702            IPackageManager pm = AppGlobals.getPackageManager();
10703            for (String pkg : extList) {
10704                try {
10705                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10706                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10707                        retList.add(info);
10708                    }
10709                } catch (RemoteException e) {
10710                }
10711            }
10712        }
10713        return retList;
10714    }
10715
10716    @Override
10717    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10718        enforceNotIsolatedCaller("getMyMemoryState");
10719        synchronized (this) {
10720            ProcessRecord proc;
10721            synchronized (mPidsSelfLocked) {
10722                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10723            }
10724            fillInProcMemInfo(proc, outInfo);
10725        }
10726    }
10727
10728    @Override
10729    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10730        if (checkCallingPermission(android.Manifest.permission.DUMP)
10731                != PackageManager.PERMISSION_GRANTED) {
10732            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10733                    + Binder.getCallingPid()
10734                    + ", uid=" + Binder.getCallingUid()
10735                    + " without permission "
10736                    + android.Manifest.permission.DUMP);
10737            return;
10738        }
10739
10740        boolean dumpAll = false;
10741        boolean dumpClient = false;
10742        String dumpPackage = null;
10743
10744        int opti = 0;
10745        while (opti < args.length) {
10746            String opt = args[opti];
10747            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10748                break;
10749            }
10750            opti++;
10751            if ("-a".equals(opt)) {
10752                dumpAll = true;
10753            } else if ("-c".equals(opt)) {
10754                dumpClient = true;
10755            } else if ("-h".equals(opt)) {
10756                pw.println("Activity manager dump options:");
10757                pw.println("  [-a] [-c] [-h] [cmd] ...");
10758                pw.println("  cmd may be one of:");
10759                pw.println("    a[ctivities]: activity stack state");
10760                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10761                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10762                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10763                pw.println("    o[om]: out of memory management");
10764                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10765                pw.println("    provider [COMP_SPEC]: provider client-side state");
10766                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10767                pw.println("    service [COMP_SPEC]: service client-side state");
10768                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10769                pw.println("    all: dump all activities");
10770                pw.println("    top: dump the top activity");
10771                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10772                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10773                pw.println("    a partial substring in a component name, a");
10774                pw.println("    hex object identifier.");
10775                pw.println("  -a: include all available server state.");
10776                pw.println("  -c: include client state.");
10777                return;
10778            } else {
10779                pw.println("Unknown argument: " + opt + "; use -h for help");
10780            }
10781        }
10782
10783        long origId = Binder.clearCallingIdentity();
10784        boolean more = false;
10785        // Is the caller requesting to dump a particular piece of data?
10786        if (opti < args.length) {
10787            String cmd = args[opti];
10788            opti++;
10789            if ("activities".equals(cmd) || "a".equals(cmd)) {
10790                synchronized (this) {
10791                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10792                }
10793            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10794                String[] newArgs;
10795                String name;
10796                if (opti >= args.length) {
10797                    name = null;
10798                    newArgs = EMPTY_STRING_ARRAY;
10799                } else {
10800                    name = args[opti];
10801                    opti++;
10802                    newArgs = new String[args.length - opti];
10803                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10804                            args.length - opti);
10805                }
10806                synchronized (this) {
10807                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10808                }
10809            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10810                String[] newArgs;
10811                String name;
10812                if (opti >= args.length) {
10813                    name = null;
10814                    newArgs = EMPTY_STRING_ARRAY;
10815                } else {
10816                    name = args[opti];
10817                    opti++;
10818                    newArgs = new String[args.length - opti];
10819                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10820                            args.length - opti);
10821                }
10822                synchronized (this) {
10823                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10824                }
10825            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10826                String[] newArgs;
10827                String name;
10828                if (opti >= args.length) {
10829                    name = null;
10830                    newArgs = EMPTY_STRING_ARRAY;
10831                } else {
10832                    name = args[opti];
10833                    opti++;
10834                    newArgs = new String[args.length - opti];
10835                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10836                            args.length - opti);
10837                }
10838                synchronized (this) {
10839                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10840                }
10841            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10842                synchronized (this) {
10843                    dumpOomLocked(fd, pw, args, opti, true);
10844                }
10845            } else if ("provider".equals(cmd)) {
10846                String[] newArgs;
10847                String name;
10848                if (opti >= args.length) {
10849                    name = null;
10850                    newArgs = EMPTY_STRING_ARRAY;
10851                } else {
10852                    name = args[opti];
10853                    opti++;
10854                    newArgs = new String[args.length - opti];
10855                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10856                }
10857                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10858                    pw.println("No providers match: " + name);
10859                    pw.println("Use -h for help.");
10860                }
10861            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10862                synchronized (this) {
10863                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10864                }
10865            } else if ("service".equals(cmd)) {
10866                String[] newArgs;
10867                String name;
10868                if (opti >= args.length) {
10869                    name = null;
10870                    newArgs = EMPTY_STRING_ARRAY;
10871                } else {
10872                    name = args[opti];
10873                    opti++;
10874                    newArgs = new String[args.length - opti];
10875                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10876                            args.length - opti);
10877                }
10878                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10879                    pw.println("No services match: " + name);
10880                    pw.println("Use -h for help.");
10881                }
10882            } else if ("package".equals(cmd)) {
10883                String[] newArgs;
10884                if (opti >= args.length) {
10885                    pw.println("package: no package name specified");
10886                    pw.println("Use -h for help.");
10887                } else {
10888                    dumpPackage = args[opti];
10889                    opti++;
10890                    newArgs = new String[args.length - opti];
10891                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10892                            args.length - opti);
10893                    args = newArgs;
10894                    opti = 0;
10895                    more = true;
10896                }
10897            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10898                synchronized (this) {
10899                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10900                }
10901            } else {
10902                // Dumping a single activity?
10903                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10904                    pw.println("Bad activity command, or no activities match: " + cmd);
10905                    pw.println("Use -h for help.");
10906                }
10907            }
10908            if (!more) {
10909                Binder.restoreCallingIdentity(origId);
10910                return;
10911            }
10912        }
10913
10914        // No piece of data specified, dump everything.
10915        synchronized (this) {
10916            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10917            pw.println();
10918            if (dumpAll) {
10919                pw.println("-------------------------------------------------------------------------------");
10920            }
10921            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10922            pw.println();
10923            if (dumpAll) {
10924                pw.println("-------------------------------------------------------------------------------");
10925            }
10926            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10927            pw.println();
10928            if (dumpAll) {
10929                pw.println("-------------------------------------------------------------------------------");
10930            }
10931            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10932            pw.println();
10933            if (dumpAll) {
10934                pw.println("-------------------------------------------------------------------------------");
10935            }
10936            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10937            pw.println();
10938            if (dumpAll) {
10939                pw.println("-------------------------------------------------------------------------------");
10940            }
10941            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10942        }
10943        Binder.restoreCallingIdentity(origId);
10944    }
10945
10946    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10947            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10948        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10949
10950        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10951                dumpPackage);
10952        boolean needSep = printedAnything;
10953
10954        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10955                dumpPackage, needSep, "  mFocusedActivity: ");
10956        if (printed) {
10957            printedAnything = true;
10958            needSep = false;
10959        }
10960
10961        if (dumpPackage == null) {
10962            if (needSep) {
10963                pw.println();
10964            }
10965            needSep = true;
10966            printedAnything = true;
10967            mStackSupervisor.dump(pw, "  ");
10968        }
10969
10970        if (mRecentTasks.size() > 0) {
10971            boolean printedHeader = false;
10972
10973            final int N = mRecentTasks.size();
10974            for (int i=0; i<N; i++) {
10975                TaskRecord tr = mRecentTasks.get(i);
10976                if (dumpPackage != null) {
10977                    if (tr.realActivity == null ||
10978                            !dumpPackage.equals(tr.realActivity)) {
10979                        continue;
10980                    }
10981                }
10982                if (!printedHeader) {
10983                    if (needSep) {
10984                        pw.println();
10985                    }
10986                    pw.println("  Recent tasks:");
10987                    printedHeader = true;
10988                    printedAnything = true;
10989                }
10990                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10991                        pw.println(tr);
10992                if (dumpAll) {
10993                    mRecentTasks.get(i).dump(pw, "    ");
10994                }
10995            }
10996        }
10997
10998        if (!printedAnything) {
10999            pw.println("  (nothing)");
11000        }
11001    }
11002
11003    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11004            int opti, boolean dumpAll, String dumpPackage) {
11005        boolean needSep = false;
11006        boolean printedAnything = false;
11007        int numPers = 0;
11008
11009        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11010
11011        if (dumpAll) {
11012            final int NP = mProcessNames.getMap().size();
11013            for (int ip=0; ip<NP; ip++) {
11014                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11015                final int NA = procs.size();
11016                for (int ia=0; ia<NA; ia++) {
11017                    ProcessRecord r = procs.valueAt(ia);
11018                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11019                        continue;
11020                    }
11021                    if (!needSep) {
11022                        pw.println("  All known processes:");
11023                        needSep = true;
11024                        printedAnything = true;
11025                    }
11026                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11027                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11028                        pw.print(" "); pw.println(r);
11029                    r.dump(pw, "    ");
11030                    if (r.persistent) {
11031                        numPers++;
11032                    }
11033                }
11034            }
11035        }
11036
11037        if (mIsolatedProcesses.size() > 0) {
11038            boolean printed = false;
11039            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11040                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11041                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11042                    continue;
11043                }
11044                if (!printed) {
11045                    if (needSep) {
11046                        pw.println();
11047                    }
11048                    pw.println("  Isolated process list (sorted by uid):");
11049                    printedAnything = true;
11050                    printed = true;
11051                    needSep = true;
11052                }
11053                pw.println(String.format("%sIsolated #%2d: %s",
11054                        "    ", i, r.toString()));
11055            }
11056        }
11057
11058        if (mLruProcesses.size() > 0) {
11059            if (needSep) {
11060                pw.println();
11061            }
11062            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11063                    pw.print(" total, non-act at ");
11064                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11065                    pw.print(", non-svc at ");
11066                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11067                    pw.println("):");
11068            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11069            needSep = true;
11070            printedAnything = true;
11071        }
11072
11073        if (dumpAll || dumpPackage != null) {
11074            synchronized (mPidsSelfLocked) {
11075                boolean printed = false;
11076                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11077                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11078                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11079                        continue;
11080                    }
11081                    if (!printed) {
11082                        if (needSep) pw.println();
11083                        needSep = true;
11084                        pw.println("  PID mappings:");
11085                        printed = true;
11086                        printedAnything = true;
11087                    }
11088                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11089                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11090                }
11091            }
11092        }
11093
11094        if (mForegroundProcesses.size() > 0) {
11095            synchronized (mPidsSelfLocked) {
11096                boolean printed = false;
11097                for (int i=0; i<mForegroundProcesses.size(); i++) {
11098                    ProcessRecord r = mPidsSelfLocked.get(
11099                            mForegroundProcesses.valueAt(i).pid);
11100                    if (dumpPackage != null && (r == null
11101                            || !r.pkgList.containsKey(dumpPackage))) {
11102                        continue;
11103                    }
11104                    if (!printed) {
11105                        if (needSep) pw.println();
11106                        needSep = true;
11107                        pw.println("  Foreground Processes:");
11108                        printed = true;
11109                        printedAnything = true;
11110                    }
11111                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11112                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11113                }
11114            }
11115        }
11116
11117        if (mPersistentStartingProcesses.size() > 0) {
11118            if (needSep) pw.println();
11119            needSep = true;
11120            printedAnything = true;
11121            pw.println("  Persisent processes that are starting:");
11122            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11123                    "Starting Norm", "Restarting PERS", dumpPackage);
11124        }
11125
11126        if (mRemovedProcesses.size() > 0) {
11127            if (needSep) pw.println();
11128            needSep = true;
11129            printedAnything = true;
11130            pw.println("  Processes that are being removed:");
11131            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11132                    "Removed Norm", "Removed PERS", dumpPackage);
11133        }
11134
11135        if (mProcessesOnHold.size() > 0) {
11136            if (needSep) pw.println();
11137            needSep = true;
11138            printedAnything = true;
11139            pw.println("  Processes that are on old until the system is ready:");
11140            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11141                    "OnHold Norm", "OnHold PERS", dumpPackage);
11142        }
11143
11144        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11145
11146        if (mProcessCrashTimes.getMap().size() > 0) {
11147            boolean printed = false;
11148            long now = SystemClock.uptimeMillis();
11149            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11150            final int NP = pmap.size();
11151            for (int ip=0; ip<NP; ip++) {
11152                String pname = pmap.keyAt(ip);
11153                SparseArray<Long> uids = pmap.valueAt(ip);
11154                final int N = uids.size();
11155                for (int i=0; i<N; i++) {
11156                    int puid = uids.keyAt(i);
11157                    ProcessRecord r = mProcessNames.get(pname, puid);
11158                    if (dumpPackage != null && (r == null
11159                            || !r.pkgList.containsKey(dumpPackage))) {
11160                        continue;
11161                    }
11162                    if (!printed) {
11163                        if (needSep) pw.println();
11164                        needSep = true;
11165                        pw.println("  Time since processes crashed:");
11166                        printed = true;
11167                        printedAnything = true;
11168                    }
11169                    pw.print("    Process "); pw.print(pname);
11170                            pw.print(" uid "); pw.print(puid);
11171                            pw.print(": last crashed ");
11172                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11173                            pw.println(" ago");
11174                }
11175            }
11176        }
11177
11178        if (mBadProcesses.getMap().size() > 0) {
11179            boolean printed = false;
11180            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11181            final int NP = pmap.size();
11182            for (int ip=0; ip<NP; ip++) {
11183                String pname = pmap.keyAt(ip);
11184                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11185                final int N = uids.size();
11186                for (int i=0; i<N; i++) {
11187                    int puid = uids.keyAt(i);
11188                    ProcessRecord r = mProcessNames.get(pname, puid);
11189                    if (dumpPackage != null && (r == null
11190                            || !r.pkgList.containsKey(dumpPackage))) {
11191                        continue;
11192                    }
11193                    if (!printed) {
11194                        if (needSep) pw.println();
11195                        needSep = true;
11196                        pw.println("  Bad processes:");
11197                        printedAnything = true;
11198                    }
11199                    BadProcessInfo info = uids.valueAt(i);
11200                    pw.print("    Bad process "); pw.print(pname);
11201                            pw.print(" uid "); pw.print(puid);
11202                            pw.print(": crashed at time "); pw.println(info.time);
11203                    if (info.shortMsg != null) {
11204                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11205                    }
11206                    if (info.longMsg != null) {
11207                        pw.print("      Long msg: "); pw.println(info.longMsg);
11208                    }
11209                    if (info.stack != null) {
11210                        pw.println("      Stack:");
11211                        int lastPos = 0;
11212                        for (int pos=0; pos<info.stack.length(); pos++) {
11213                            if (info.stack.charAt(pos) == '\n') {
11214                                pw.print("        ");
11215                                pw.write(info.stack, lastPos, pos-lastPos);
11216                                pw.println();
11217                                lastPos = pos+1;
11218                            }
11219                        }
11220                        if (lastPos < info.stack.length()) {
11221                            pw.print("        ");
11222                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11223                            pw.println();
11224                        }
11225                    }
11226                }
11227            }
11228        }
11229
11230        if (dumpPackage == null) {
11231            pw.println();
11232            needSep = false;
11233            pw.println("  mStartedUsers:");
11234            for (int i=0; i<mStartedUsers.size(); i++) {
11235                UserStartedState uss = mStartedUsers.valueAt(i);
11236                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11237                        pw.print(": "); uss.dump("", pw);
11238            }
11239            pw.print("  mStartedUserArray: [");
11240            for (int i=0; i<mStartedUserArray.length; i++) {
11241                if (i > 0) pw.print(", ");
11242                pw.print(mStartedUserArray[i]);
11243            }
11244            pw.println("]");
11245            pw.print("  mUserLru: [");
11246            for (int i=0; i<mUserLru.size(); i++) {
11247                if (i > 0) pw.print(", ");
11248                pw.print(mUserLru.get(i));
11249            }
11250            pw.println("]");
11251            if (dumpAll) {
11252                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11253            }
11254        }
11255        if (mHomeProcess != null && (dumpPackage == null
11256                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11257            if (needSep) {
11258                pw.println();
11259                needSep = false;
11260            }
11261            pw.println("  mHomeProcess: " + mHomeProcess);
11262        }
11263        if (mPreviousProcess != null && (dumpPackage == null
11264                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11265            if (needSep) {
11266                pw.println();
11267                needSep = false;
11268            }
11269            pw.println("  mPreviousProcess: " + mPreviousProcess);
11270        }
11271        if (dumpAll) {
11272            StringBuilder sb = new StringBuilder(128);
11273            sb.append("  mPreviousProcessVisibleTime: ");
11274            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11275            pw.println(sb);
11276        }
11277        if (mHeavyWeightProcess != null && (dumpPackage == null
11278                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11279            if (needSep) {
11280                pw.println();
11281                needSep = false;
11282            }
11283            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11284        }
11285        if (dumpPackage == null) {
11286            pw.println("  mConfiguration: " + mConfiguration);
11287        }
11288        if (dumpAll) {
11289            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11290            if (mCompatModePackages.getPackages().size() > 0) {
11291                boolean printed = false;
11292                for (Map.Entry<String, Integer> entry
11293                        : mCompatModePackages.getPackages().entrySet()) {
11294                    String pkg = entry.getKey();
11295                    int mode = entry.getValue();
11296                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11297                        continue;
11298                    }
11299                    if (!printed) {
11300                        pw.println("  mScreenCompatPackages:");
11301                        printed = true;
11302                    }
11303                    pw.print("    "); pw.print(pkg); pw.print(": ");
11304                            pw.print(mode); pw.println();
11305                }
11306            }
11307        }
11308        if (dumpPackage == null) {
11309            if (mSleeping || mWentToSleep || mLockScreenShown) {
11310                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11311                        + " mLockScreenShown " + mLockScreenShown);
11312            }
11313            if (mShuttingDown || mRunningVoice) {
11314                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11315            }
11316        }
11317        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11318                || mOrigWaitForDebugger) {
11319            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11320                    || dumpPackage.equals(mOrigDebugApp)) {
11321                if (needSep) {
11322                    pw.println();
11323                    needSep = false;
11324                }
11325                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11326                        + " mDebugTransient=" + mDebugTransient
11327                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11328            }
11329        }
11330        if (mOpenGlTraceApp != null) {
11331            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11332                if (needSep) {
11333                    pw.println();
11334                    needSep = false;
11335                }
11336                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11337            }
11338        }
11339        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11340                || mProfileFd != null) {
11341            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11342                if (needSep) {
11343                    pw.println();
11344                    needSep = false;
11345                }
11346                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11347                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11348                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11349                        + mAutoStopProfiler);
11350            }
11351        }
11352        if (dumpPackage == null) {
11353            if (mAlwaysFinishActivities || mController != null) {
11354                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11355                        + " mController=" + mController);
11356            }
11357            if (dumpAll) {
11358                pw.println("  Total persistent processes: " + numPers);
11359                pw.println("  mProcessesReady=" + mProcessesReady
11360                        + " mSystemReady=" + mSystemReady);
11361                pw.println("  mBooting=" + mBooting
11362                        + " mBooted=" + mBooted
11363                        + " mFactoryTest=" + mFactoryTest);
11364                pw.print("  mLastPowerCheckRealtime=");
11365                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11366                        pw.println("");
11367                pw.print("  mLastPowerCheckUptime=");
11368                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11369                        pw.println("");
11370                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11371                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11372                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11373                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11374                        + " (" + mLruProcesses.size() + " total)"
11375                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11376                        + " mNumServiceProcs=" + mNumServiceProcs
11377                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11378                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11379                        + " mLastMemoryLevel" + mLastMemoryLevel
11380                        + " mLastNumProcesses" + mLastNumProcesses);
11381                long now = SystemClock.uptimeMillis();
11382                pw.print("  mLastIdleTime=");
11383                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11384                        pw.print(" mLowRamSinceLastIdle=");
11385                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11386                        pw.println();
11387            }
11388        }
11389
11390        if (!printedAnything) {
11391            pw.println("  (nothing)");
11392        }
11393    }
11394
11395    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11396            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11397        if (mProcessesToGc.size() > 0) {
11398            boolean printed = false;
11399            long now = SystemClock.uptimeMillis();
11400            for (int i=0; i<mProcessesToGc.size(); i++) {
11401                ProcessRecord proc = mProcessesToGc.get(i);
11402                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11403                    continue;
11404                }
11405                if (!printed) {
11406                    if (needSep) pw.println();
11407                    needSep = true;
11408                    pw.println("  Processes that are waiting to GC:");
11409                    printed = true;
11410                }
11411                pw.print("    Process "); pw.println(proc);
11412                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11413                        pw.print(", last gced=");
11414                        pw.print(now-proc.lastRequestedGc);
11415                        pw.print(" ms ago, last lowMem=");
11416                        pw.print(now-proc.lastLowMemory);
11417                        pw.println(" ms ago");
11418
11419            }
11420        }
11421        return needSep;
11422    }
11423
11424    void printOomLevel(PrintWriter pw, String name, int adj) {
11425        pw.print("    ");
11426        if (adj >= 0) {
11427            pw.print(' ');
11428            if (adj < 10) pw.print(' ');
11429        } else {
11430            if (adj > -10) pw.print(' ');
11431        }
11432        pw.print(adj);
11433        pw.print(": ");
11434        pw.print(name);
11435        pw.print(" (");
11436        pw.print(mProcessList.getMemLevel(adj)/1024);
11437        pw.println(" kB)");
11438    }
11439
11440    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11441            int opti, boolean dumpAll) {
11442        boolean needSep = false;
11443
11444        if (mLruProcesses.size() > 0) {
11445            if (needSep) pw.println();
11446            needSep = true;
11447            pw.println("  OOM levels:");
11448            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11449            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11450            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11451            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11452            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11453            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11454            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11455            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11456            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11457            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11458            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11459            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11460            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11461
11462            if (needSep) pw.println();
11463            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11464                    pw.print(" total, non-act at ");
11465                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11466                    pw.print(", non-svc at ");
11467                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11468                    pw.println("):");
11469            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11470            needSep = true;
11471        }
11472
11473        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11474
11475        pw.println();
11476        pw.println("  mHomeProcess: " + mHomeProcess);
11477        pw.println("  mPreviousProcess: " + mPreviousProcess);
11478        if (mHeavyWeightProcess != null) {
11479            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11480        }
11481
11482        return true;
11483    }
11484
11485    /**
11486     * There are three ways to call this:
11487     *  - no provider specified: dump all the providers
11488     *  - a flattened component name that matched an existing provider was specified as the
11489     *    first arg: dump that one provider
11490     *  - the first arg isn't the flattened component name of an existing provider:
11491     *    dump all providers whose component contains the first arg as a substring
11492     */
11493    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11494            int opti, boolean dumpAll) {
11495        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11496    }
11497
11498    static class ItemMatcher {
11499        ArrayList<ComponentName> components;
11500        ArrayList<String> strings;
11501        ArrayList<Integer> objects;
11502        boolean all;
11503
11504        ItemMatcher() {
11505            all = true;
11506        }
11507
11508        void build(String name) {
11509            ComponentName componentName = ComponentName.unflattenFromString(name);
11510            if (componentName != null) {
11511                if (components == null) {
11512                    components = new ArrayList<ComponentName>();
11513                }
11514                components.add(componentName);
11515                all = false;
11516            } else {
11517                int objectId = 0;
11518                // Not a '/' separated full component name; maybe an object ID?
11519                try {
11520                    objectId = Integer.parseInt(name, 16);
11521                    if (objects == null) {
11522                        objects = new ArrayList<Integer>();
11523                    }
11524                    objects.add(objectId);
11525                    all = false;
11526                } catch (RuntimeException e) {
11527                    // Not an integer; just do string match.
11528                    if (strings == null) {
11529                        strings = new ArrayList<String>();
11530                    }
11531                    strings.add(name);
11532                    all = false;
11533                }
11534            }
11535        }
11536
11537        int build(String[] args, int opti) {
11538            for (; opti<args.length; opti++) {
11539                String name = args[opti];
11540                if ("--".equals(name)) {
11541                    return opti+1;
11542                }
11543                build(name);
11544            }
11545            return opti;
11546        }
11547
11548        boolean match(Object object, ComponentName comp) {
11549            if (all) {
11550                return true;
11551            }
11552            if (components != null) {
11553                for (int i=0; i<components.size(); i++) {
11554                    if (components.get(i).equals(comp)) {
11555                        return true;
11556                    }
11557                }
11558            }
11559            if (objects != null) {
11560                for (int i=0; i<objects.size(); i++) {
11561                    if (System.identityHashCode(object) == objects.get(i)) {
11562                        return true;
11563                    }
11564                }
11565            }
11566            if (strings != null) {
11567                String flat = comp.flattenToString();
11568                for (int i=0; i<strings.size(); i++) {
11569                    if (flat.contains(strings.get(i))) {
11570                        return true;
11571                    }
11572                }
11573            }
11574            return false;
11575        }
11576    }
11577
11578    /**
11579     * There are three things that cmd can be:
11580     *  - a flattened component name that matches an existing activity
11581     *  - the cmd arg isn't the flattened component name of an existing activity:
11582     *    dump all activity whose component contains the cmd as a substring
11583     *  - A hex number of the ActivityRecord object instance.
11584     */
11585    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11586            int opti, boolean dumpAll) {
11587        ArrayList<ActivityRecord> activities;
11588
11589        synchronized (this) {
11590            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11591        }
11592
11593        if (activities.size() <= 0) {
11594            return false;
11595        }
11596
11597        String[] newArgs = new String[args.length - opti];
11598        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11599
11600        TaskRecord lastTask = null;
11601        boolean needSep = false;
11602        for (int i=activities.size()-1; i>=0; i--) {
11603            ActivityRecord r = activities.get(i);
11604            if (needSep) {
11605                pw.println();
11606            }
11607            needSep = true;
11608            synchronized (this) {
11609                if (lastTask != r.task) {
11610                    lastTask = r.task;
11611                    pw.print("TASK "); pw.print(lastTask.affinity);
11612                            pw.print(" id="); pw.println(lastTask.taskId);
11613                    if (dumpAll) {
11614                        lastTask.dump(pw, "  ");
11615                    }
11616                }
11617            }
11618            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11619        }
11620        return true;
11621    }
11622
11623    /**
11624     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11625     * there is a thread associated with the activity.
11626     */
11627    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11628            final ActivityRecord r, String[] args, boolean dumpAll) {
11629        String innerPrefix = prefix + "  ";
11630        synchronized (this) {
11631            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11632                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11633                    pw.print(" pid=");
11634                    if (r.app != null) pw.println(r.app.pid);
11635                    else pw.println("(not running)");
11636            if (dumpAll) {
11637                r.dump(pw, innerPrefix);
11638            }
11639        }
11640        if (r.app != null && r.app.thread != null) {
11641            // flush anything that is already in the PrintWriter since the thread is going
11642            // to write to the file descriptor directly
11643            pw.flush();
11644            try {
11645                TransferPipe tp = new TransferPipe();
11646                try {
11647                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11648                            r.appToken, innerPrefix, args);
11649                    tp.go(fd);
11650                } finally {
11651                    tp.kill();
11652                }
11653            } catch (IOException e) {
11654                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11655            } catch (RemoteException e) {
11656                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11657            }
11658        }
11659    }
11660
11661    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11662            int opti, boolean dumpAll, String dumpPackage) {
11663        boolean needSep = false;
11664        boolean onlyHistory = false;
11665        boolean printedAnything = false;
11666
11667        if ("history".equals(dumpPackage)) {
11668            if (opti < args.length && "-s".equals(args[opti])) {
11669                dumpAll = false;
11670            }
11671            onlyHistory = true;
11672            dumpPackage = null;
11673        }
11674
11675        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11676        if (!onlyHistory && dumpAll) {
11677            if (mRegisteredReceivers.size() > 0) {
11678                boolean printed = false;
11679                Iterator it = mRegisteredReceivers.values().iterator();
11680                while (it.hasNext()) {
11681                    ReceiverList r = (ReceiverList)it.next();
11682                    if (dumpPackage != null && (r.app == null ||
11683                            !dumpPackage.equals(r.app.info.packageName))) {
11684                        continue;
11685                    }
11686                    if (!printed) {
11687                        pw.println("  Registered Receivers:");
11688                        needSep = true;
11689                        printed = true;
11690                        printedAnything = true;
11691                    }
11692                    pw.print("  * "); pw.println(r);
11693                    r.dump(pw, "    ");
11694                }
11695            }
11696
11697            if (mReceiverResolver.dump(pw, needSep ?
11698                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11699                    "    ", dumpPackage, false)) {
11700                needSep = true;
11701                printedAnything = true;
11702            }
11703        }
11704
11705        for (BroadcastQueue q : mBroadcastQueues) {
11706            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11707            printedAnything |= needSep;
11708        }
11709
11710        needSep = true;
11711
11712        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11713            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11714                if (needSep) {
11715                    pw.println();
11716                }
11717                needSep = true;
11718                printedAnything = true;
11719                pw.print("  Sticky broadcasts for user ");
11720                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11721                StringBuilder sb = new StringBuilder(128);
11722                for (Map.Entry<String, ArrayList<Intent>> ent
11723                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11724                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11725                    if (dumpAll) {
11726                        pw.println(":");
11727                        ArrayList<Intent> intents = ent.getValue();
11728                        final int N = intents.size();
11729                        for (int i=0; i<N; i++) {
11730                            sb.setLength(0);
11731                            sb.append("    Intent: ");
11732                            intents.get(i).toShortString(sb, false, true, false, false);
11733                            pw.println(sb.toString());
11734                            Bundle bundle = intents.get(i).getExtras();
11735                            if (bundle != null) {
11736                                pw.print("      ");
11737                                pw.println(bundle.toString());
11738                            }
11739                        }
11740                    } else {
11741                        pw.println("");
11742                    }
11743                }
11744            }
11745        }
11746
11747        if (!onlyHistory && dumpAll) {
11748            pw.println();
11749            for (BroadcastQueue queue : mBroadcastQueues) {
11750                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11751                        + queue.mBroadcastsScheduled);
11752            }
11753            pw.println("  mHandler:");
11754            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11755            needSep = true;
11756            printedAnything = true;
11757        }
11758
11759        if (!printedAnything) {
11760            pw.println("  (nothing)");
11761        }
11762    }
11763
11764    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11765            int opti, boolean dumpAll, String dumpPackage) {
11766        boolean needSep;
11767        boolean printedAnything = false;
11768
11769        ItemMatcher matcher = new ItemMatcher();
11770        matcher.build(args, opti);
11771
11772        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11773
11774        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11775        printedAnything |= needSep;
11776
11777        if (mLaunchingProviders.size() > 0) {
11778            boolean printed = false;
11779            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11780                ContentProviderRecord r = mLaunchingProviders.get(i);
11781                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11782                    continue;
11783                }
11784                if (!printed) {
11785                    if (needSep) pw.println();
11786                    needSep = true;
11787                    pw.println("  Launching content providers:");
11788                    printed = true;
11789                    printedAnything = true;
11790                }
11791                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11792                        pw.println(r);
11793            }
11794        }
11795
11796        if (mGrantedUriPermissions.size() > 0) {
11797            boolean printed = false;
11798            int dumpUid = -2;
11799            if (dumpPackage != null) {
11800                try {
11801                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11802                } catch (NameNotFoundException e) {
11803                    dumpUid = -1;
11804                }
11805            }
11806            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11807                int uid = mGrantedUriPermissions.keyAt(i);
11808                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11809                    continue;
11810                }
11811                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11812                if (!printed) {
11813                    if (needSep) pw.println();
11814                    needSep = true;
11815                    pw.println("  Granted Uri Permissions:");
11816                    printed = true;
11817                    printedAnything = true;
11818                }
11819                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11820                for (UriPermission perm : perms.values()) {
11821                    pw.print("    "); pw.println(perm);
11822                    if (dumpAll) {
11823                        perm.dump(pw, "      ");
11824                    }
11825                }
11826            }
11827        }
11828
11829        if (!printedAnything) {
11830            pw.println("  (nothing)");
11831        }
11832    }
11833
11834    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11835            int opti, boolean dumpAll, String dumpPackage) {
11836        boolean printed = false;
11837
11838        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11839
11840        if (mIntentSenderRecords.size() > 0) {
11841            Iterator<WeakReference<PendingIntentRecord>> it
11842                    = mIntentSenderRecords.values().iterator();
11843            while (it.hasNext()) {
11844                WeakReference<PendingIntentRecord> ref = it.next();
11845                PendingIntentRecord rec = ref != null ? ref.get(): null;
11846                if (dumpPackage != null && (rec == null
11847                        || !dumpPackage.equals(rec.key.packageName))) {
11848                    continue;
11849                }
11850                printed = true;
11851                if (rec != null) {
11852                    pw.print("  * "); pw.println(rec);
11853                    if (dumpAll) {
11854                        rec.dump(pw, "    ");
11855                    }
11856                } else {
11857                    pw.print("  * "); pw.println(ref);
11858                }
11859            }
11860        }
11861
11862        if (!printed) {
11863            pw.println("  (nothing)");
11864        }
11865    }
11866
11867    private static final int dumpProcessList(PrintWriter pw,
11868            ActivityManagerService service, List list,
11869            String prefix, String normalLabel, String persistentLabel,
11870            String dumpPackage) {
11871        int numPers = 0;
11872        final int N = list.size()-1;
11873        for (int i=N; i>=0; i--) {
11874            ProcessRecord r = (ProcessRecord)list.get(i);
11875            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11876                continue;
11877            }
11878            pw.println(String.format("%s%s #%2d: %s",
11879                    prefix, (r.persistent ? persistentLabel : normalLabel),
11880                    i, r.toString()));
11881            if (r.persistent) {
11882                numPers++;
11883            }
11884        }
11885        return numPers;
11886    }
11887
11888    private static final boolean dumpProcessOomList(PrintWriter pw,
11889            ActivityManagerService service, List<ProcessRecord> origList,
11890            String prefix, String normalLabel, String persistentLabel,
11891            boolean inclDetails, String dumpPackage) {
11892
11893        ArrayList<Pair<ProcessRecord, Integer>> list
11894                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11895        for (int i=0; i<origList.size(); i++) {
11896            ProcessRecord r = origList.get(i);
11897            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11898                continue;
11899            }
11900            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11901        }
11902
11903        if (list.size() <= 0) {
11904            return false;
11905        }
11906
11907        Comparator<Pair<ProcessRecord, Integer>> comparator
11908                = new Comparator<Pair<ProcessRecord, Integer>>() {
11909            @Override
11910            public int compare(Pair<ProcessRecord, Integer> object1,
11911                    Pair<ProcessRecord, Integer> object2) {
11912                if (object1.first.setAdj != object2.first.setAdj) {
11913                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11914                }
11915                if (object1.second.intValue() != object2.second.intValue()) {
11916                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11917                }
11918                return 0;
11919            }
11920        };
11921
11922        Collections.sort(list, comparator);
11923
11924        final long curRealtime = SystemClock.elapsedRealtime();
11925        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11926        final long curUptime = SystemClock.uptimeMillis();
11927        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11928
11929        for (int i=list.size()-1; i>=0; i--) {
11930            ProcessRecord r = list.get(i).first;
11931            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11932            char schedGroup;
11933            switch (r.setSchedGroup) {
11934                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11935                    schedGroup = 'B';
11936                    break;
11937                case Process.THREAD_GROUP_DEFAULT:
11938                    schedGroup = 'F';
11939                    break;
11940                default:
11941                    schedGroup = '?';
11942                    break;
11943            }
11944            char foreground;
11945            if (r.foregroundActivities) {
11946                foreground = 'A';
11947            } else if (r.foregroundServices) {
11948                foreground = 'S';
11949            } else {
11950                foreground = ' ';
11951            }
11952            String procState = ProcessList.makeProcStateString(r.curProcState);
11953            pw.print(prefix);
11954            pw.print(r.persistent ? persistentLabel : normalLabel);
11955            pw.print(" #");
11956            int num = (origList.size()-1)-list.get(i).second;
11957            if (num < 10) pw.print(' ');
11958            pw.print(num);
11959            pw.print(": ");
11960            pw.print(oomAdj);
11961            pw.print(' ');
11962            pw.print(schedGroup);
11963            pw.print('/');
11964            pw.print(foreground);
11965            pw.print('/');
11966            pw.print(procState);
11967            pw.print(" trm:");
11968            if (r.trimMemoryLevel < 10) pw.print(' ');
11969            pw.print(r.trimMemoryLevel);
11970            pw.print(' ');
11971            pw.print(r.toShortString());
11972            pw.print(" (");
11973            pw.print(r.adjType);
11974            pw.println(')');
11975            if (r.adjSource != null || r.adjTarget != null) {
11976                pw.print(prefix);
11977                pw.print("    ");
11978                if (r.adjTarget instanceof ComponentName) {
11979                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11980                } else if (r.adjTarget != null) {
11981                    pw.print(r.adjTarget.toString());
11982                } else {
11983                    pw.print("{null}");
11984                }
11985                pw.print("<=");
11986                if (r.adjSource instanceof ProcessRecord) {
11987                    pw.print("Proc{");
11988                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11989                    pw.println("}");
11990                } else if (r.adjSource != null) {
11991                    pw.println(r.adjSource.toString());
11992                } else {
11993                    pw.println("{null}");
11994                }
11995            }
11996            if (inclDetails) {
11997                pw.print(prefix);
11998                pw.print("    ");
11999                pw.print("oom: max="); pw.print(r.maxAdj);
12000                pw.print(" curRaw="); pw.print(r.curRawAdj);
12001                pw.print(" setRaw="); pw.print(r.setRawAdj);
12002                pw.print(" cur="); pw.print(r.curAdj);
12003                pw.print(" set="); pw.println(r.setAdj);
12004                pw.print(prefix);
12005                pw.print("    ");
12006                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12007                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12008                pw.print(" lastPss="); pw.print(r.lastPss);
12009                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12010                pw.print(prefix);
12011                pw.print("    ");
12012                pw.print("keeping="); pw.print(r.keeping);
12013                pw.print(" cached="); pw.print(r.cached);
12014                pw.print(" empty="); pw.print(r.empty);
12015                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12016
12017                if (!r.keeping) {
12018                    if (r.lastWakeTime != 0) {
12019                        long wtime;
12020                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12021                        synchronized (stats) {
12022                            wtime = stats.getProcessWakeTime(r.info.uid,
12023                                    r.pid, curRealtime);
12024                        }
12025                        long timeUsed = wtime - r.lastWakeTime;
12026                        pw.print(prefix);
12027                        pw.print("    ");
12028                        pw.print("keep awake over ");
12029                        TimeUtils.formatDuration(realtimeSince, pw);
12030                        pw.print(" used ");
12031                        TimeUtils.formatDuration(timeUsed, pw);
12032                        pw.print(" (");
12033                        pw.print((timeUsed*100)/realtimeSince);
12034                        pw.println("%)");
12035                    }
12036                    if (r.lastCpuTime != 0) {
12037                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12038                        pw.print(prefix);
12039                        pw.print("    ");
12040                        pw.print("run cpu over ");
12041                        TimeUtils.formatDuration(uptimeSince, pw);
12042                        pw.print(" used ");
12043                        TimeUtils.formatDuration(timeUsed, pw);
12044                        pw.print(" (");
12045                        pw.print((timeUsed*100)/uptimeSince);
12046                        pw.println("%)");
12047                    }
12048                }
12049            }
12050        }
12051        return true;
12052    }
12053
12054    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12055        ArrayList<ProcessRecord> procs;
12056        synchronized (this) {
12057            if (args != null && args.length > start
12058                    && args[start].charAt(0) != '-') {
12059                procs = new ArrayList<ProcessRecord>();
12060                int pid = -1;
12061                try {
12062                    pid = Integer.parseInt(args[start]);
12063                } catch (NumberFormatException e) {
12064                }
12065                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12066                    ProcessRecord proc = mLruProcesses.get(i);
12067                    if (proc.pid == pid) {
12068                        procs.add(proc);
12069                    } else if (proc.processName.equals(args[start])) {
12070                        procs.add(proc);
12071                    }
12072                }
12073                if (procs.size() <= 0) {
12074                    return null;
12075                }
12076            } else {
12077                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12078            }
12079        }
12080        return procs;
12081    }
12082
12083    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12084            PrintWriter pw, String[] args) {
12085        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12086        if (procs == null) {
12087            pw.println("No process found for: " + args[0]);
12088            return;
12089        }
12090
12091        long uptime = SystemClock.uptimeMillis();
12092        long realtime = SystemClock.elapsedRealtime();
12093        pw.println("Applications Graphics Acceleration Info:");
12094        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12095
12096        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12097            ProcessRecord r = procs.get(i);
12098            if (r.thread != null) {
12099                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12100                pw.flush();
12101                try {
12102                    TransferPipe tp = new TransferPipe();
12103                    try {
12104                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12105                        tp.go(fd);
12106                    } finally {
12107                        tp.kill();
12108                    }
12109                } catch (IOException e) {
12110                    pw.println("Failure while dumping the app: " + r);
12111                    pw.flush();
12112                } catch (RemoteException e) {
12113                    pw.println("Got a RemoteException while dumping the app " + r);
12114                    pw.flush();
12115                }
12116            }
12117        }
12118    }
12119
12120    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12121        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12122        if (procs == null) {
12123            pw.println("No process found for: " + args[0]);
12124            return;
12125        }
12126
12127        pw.println("Applications Database Info:");
12128
12129        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12130            ProcessRecord r = procs.get(i);
12131            if (r.thread != null) {
12132                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12133                pw.flush();
12134                try {
12135                    TransferPipe tp = new TransferPipe();
12136                    try {
12137                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12138                        tp.go(fd);
12139                    } finally {
12140                        tp.kill();
12141                    }
12142                } catch (IOException e) {
12143                    pw.println("Failure while dumping the app: " + r);
12144                    pw.flush();
12145                } catch (RemoteException e) {
12146                    pw.println("Got a RemoteException while dumping the app " + r);
12147                    pw.flush();
12148                }
12149            }
12150        }
12151    }
12152
12153    final static class MemItem {
12154        final boolean isProc;
12155        final String label;
12156        final String shortLabel;
12157        final long pss;
12158        final int id;
12159        final boolean hasActivities;
12160        ArrayList<MemItem> subitems;
12161
12162        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12163                boolean _hasActivities) {
12164            isProc = true;
12165            label = _label;
12166            shortLabel = _shortLabel;
12167            pss = _pss;
12168            id = _id;
12169            hasActivities = _hasActivities;
12170        }
12171
12172        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12173            isProc = false;
12174            label = _label;
12175            shortLabel = _shortLabel;
12176            pss = _pss;
12177            id = _id;
12178            hasActivities = false;
12179        }
12180    }
12181
12182    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12183            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12184        if (sort && !isCompact) {
12185            Collections.sort(items, new Comparator<MemItem>() {
12186                @Override
12187                public int compare(MemItem lhs, MemItem rhs) {
12188                    if (lhs.pss < rhs.pss) {
12189                        return 1;
12190                    } else if (lhs.pss > rhs.pss) {
12191                        return -1;
12192                    }
12193                    return 0;
12194                }
12195            });
12196        }
12197
12198        for (int i=0; i<items.size(); i++) {
12199            MemItem mi = items.get(i);
12200            if (!isCompact) {
12201                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12202            } else if (mi.isProc) {
12203                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12204                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12205                pw.println(mi.hasActivities ? ",a" : ",e");
12206            } else {
12207                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12208                pw.println(mi.pss);
12209            }
12210            if (mi.subitems != null) {
12211                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12212                        true, isCompact);
12213            }
12214        }
12215    }
12216
12217    // These are in KB.
12218    static final long[] DUMP_MEM_BUCKETS = new long[] {
12219        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12220        120*1024, 160*1024, 200*1024,
12221        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12222        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12223    };
12224
12225    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12226            boolean stackLike) {
12227        int start = label.lastIndexOf('.');
12228        if (start >= 0) start++;
12229        else start = 0;
12230        int end = label.length();
12231        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12232            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12233                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12234                out.append(bucket);
12235                out.append(stackLike ? "MB." : "MB ");
12236                out.append(label, start, end);
12237                return;
12238            }
12239        }
12240        out.append(memKB/1024);
12241        out.append(stackLike ? "MB." : "MB ");
12242        out.append(label, start, end);
12243    }
12244
12245    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12246            ProcessList.NATIVE_ADJ,
12247            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12248            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12249            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12250            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12251            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12252    };
12253    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12254            "Native",
12255            "System", "Persistent", "Foreground",
12256            "Visible", "Perceptible",
12257            "Heavy Weight", "Backup",
12258            "A Services", "Home",
12259            "Previous", "B Services", "Cached"
12260    };
12261    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12262            "native",
12263            "sys", "pers", "fore",
12264            "vis", "percept",
12265            "heavy", "backup",
12266            "servicea", "home",
12267            "prev", "serviceb", "cached"
12268    };
12269
12270    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12271            long realtime, boolean isCheckinRequest, boolean isCompact) {
12272        if (isCheckinRequest || isCompact) {
12273            // short checkin version
12274            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12275        } else {
12276            pw.println("Applications Memory Usage (kB):");
12277            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12278        }
12279    }
12280
12281    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12282            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12283        boolean dumpDetails = false;
12284        boolean dumpFullDetails = false;
12285        boolean dumpDalvik = false;
12286        boolean oomOnly = false;
12287        boolean isCompact = false;
12288        boolean localOnly = false;
12289
12290        int opti = 0;
12291        while (opti < args.length) {
12292            String opt = args[opti];
12293            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12294                break;
12295            }
12296            opti++;
12297            if ("-a".equals(opt)) {
12298                dumpDetails = true;
12299                dumpFullDetails = true;
12300                dumpDalvik = true;
12301            } else if ("-d".equals(opt)) {
12302                dumpDalvik = true;
12303            } else if ("-c".equals(opt)) {
12304                isCompact = true;
12305            } else if ("--oom".equals(opt)) {
12306                oomOnly = true;
12307            } else if ("--local".equals(opt)) {
12308                localOnly = true;
12309            } else if ("-h".equals(opt)) {
12310                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12311                pw.println("  -a: include all available information for each process.");
12312                pw.println("  -d: include dalvik details when dumping process details.");
12313                pw.println("  -c: dump in a compact machine-parseable representation.");
12314                pw.println("  --oom: only show processes organized by oom adj.");
12315                pw.println("  --local: only collect details locally, don't call process.");
12316                pw.println("If [process] is specified it can be the name or ");
12317                pw.println("pid of a specific process to dump.");
12318                return;
12319            } else {
12320                pw.println("Unknown argument: " + opt + "; use -h for help");
12321            }
12322        }
12323
12324        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12325        long uptime = SystemClock.uptimeMillis();
12326        long realtime = SystemClock.elapsedRealtime();
12327        final long[] tmpLong = new long[1];
12328
12329        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12330        if (procs == null) {
12331            // No Java processes.  Maybe they want to print a native process.
12332            if (args != null && args.length > opti
12333                    && args[opti].charAt(0) != '-') {
12334                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12335                        = new ArrayList<ProcessCpuTracker.Stats>();
12336                updateCpuStatsNow();
12337                int findPid = -1;
12338                try {
12339                    findPid = Integer.parseInt(args[opti]);
12340                } catch (NumberFormatException e) {
12341                }
12342                synchronized (mProcessCpuThread) {
12343                    final int N = mProcessCpuTracker.countStats();
12344                    for (int i=0; i<N; i++) {
12345                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12346                        if (st.pid == findPid || (st.baseName != null
12347                                && st.baseName.equals(args[opti]))) {
12348                            nativeProcs.add(st);
12349                        }
12350                    }
12351                }
12352                if (nativeProcs.size() > 0) {
12353                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12354                            isCompact);
12355                    Debug.MemoryInfo mi = null;
12356                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12357                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12358                        final int pid = r.pid;
12359                        if (!isCheckinRequest && dumpDetails) {
12360                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12361                        }
12362                        if (mi == null) {
12363                            mi = new Debug.MemoryInfo();
12364                        }
12365                        if (dumpDetails || (!brief && !oomOnly)) {
12366                            Debug.getMemoryInfo(pid, mi);
12367                        } else {
12368                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12369                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12370                        }
12371                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12372                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12373                        if (isCheckinRequest) {
12374                            pw.println();
12375                        }
12376                    }
12377                    return;
12378                }
12379            }
12380            pw.println("No process found for: " + args[opti]);
12381            return;
12382        }
12383
12384        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12385            dumpDetails = true;
12386        }
12387
12388        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12389
12390        String[] innerArgs = new String[args.length-opti];
12391        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12392
12393        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12394        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12395        long nativePss=0, dalvikPss=0, otherPss=0;
12396        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12397
12398        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12399        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12400                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12401
12402        long totalPss = 0;
12403        long cachedPss = 0;
12404
12405        Debug.MemoryInfo mi = null;
12406        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12407            final ProcessRecord r = procs.get(i);
12408            final IApplicationThread thread;
12409            final int pid;
12410            final int oomAdj;
12411            final boolean hasActivities;
12412            synchronized (this) {
12413                thread = r.thread;
12414                pid = r.pid;
12415                oomAdj = r.getSetAdjWithServices();
12416                hasActivities = r.activities.size() > 0;
12417            }
12418            if (thread != null) {
12419                if (!isCheckinRequest && dumpDetails) {
12420                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12421                }
12422                if (mi == null) {
12423                    mi = new Debug.MemoryInfo();
12424                }
12425                if (dumpDetails || (!brief && !oomOnly)) {
12426                    Debug.getMemoryInfo(pid, mi);
12427                } else {
12428                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12429                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12430                }
12431                if (dumpDetails) {
12432                    if (localOnly) {
12433                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12434                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12435                        if (isCheckinRequest) {
12436                            pw.println();
12437                        }
12438                    } else {
12439                        try {
12440                            pw.flush();
12441                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12442                                    dumpDalvik, innerArgs);
12443                        } catch (RemoteException e) {
12444                            if (!isCheckinRequest) {
12445                                pw.println("Got RemoteException!");
12446                                pw.flush();
12447                            }
12448                        }
12449                    }
12450                }
12451
12452                final long myTotalPss = mi.getTotalPss();
12453                final long myTotalUss = mi.getTotalUss();
12454
12455                synchronized (this) {
12456                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12457                        // Record this for posterity if the process has been stable.
12458                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12459                    }
12460                }
12461
12462                if (!isCheckinRequest && mi != null) {
12463                    totalPss += myTotalPss;
12464                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12465                            (hasActivities ? " / activities)" : ")"),
12466                            r.processName, myTotalPss, pid, hasActivities);
12467                    procMems.add(pssItem);
12468                    procMemsMap.put(pid, pssItem);
12469
12470                    nativePss += mi.nativePss;
12471                    dalvikPss += mi.dalvikPss;
12472                    otherPss += mi.otherPss;
12473                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12474                        long mem = mi.getOtherPss(j);
12475                        miscPss[j] += mem;
12476                        otherPss -= mem;
12477                    }
12478
12479                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12480                        cachedPss += myTotalPss;
12481                    }
12482
12483                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12484                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12485                                || oomIndex == (oomPss.length-1)) {
12486                            oomPss[oomIndex] += myTotalPss;
12487                            if (oomProcs[oomIndex] == null) {
12488                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12489                            }
12490                            oomProcs[oomIndex].add(pssItem);
12491                            break;
12492                        }
12493                    }
12494                }
12495            }
12496        }
12497
12498        if (!isCheckinRequest && procs.size() > 1) {
12499            // If we are showing aggregations, also look for native processes to
12500            // include so that our aggregations are more accurate.
12501            updateCpuStatsNow();
12502            synchronized (mProcessCpuThread) {
12503                final int N = mProcessCpuTracker.countStats();
12504                for (int i=0; i<N; i++) {
12505                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12506                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12507                        if (mi == null) {
12508                            mi = new Debug.MemoryInfo();
12509                        }
12510                        if (!brief && !oomOnly) {
12511                            Debug.getMemoryInfo(st.pid, mi);
12512                        } else {
12513                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12514                            mi.nativePrivateDirty = (int)tmpLong[0];
12515                        }
12516
12517                        final long myTotalPss = mi.getTotalPss();
12518                        totalPss += myTotalPss;
12519
12520                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12521                                st.name, myTotalPss, st.pid, false);
12522                        procMems.add(pssItem);
12523
12524                        nativePss += mi.nativePss;
12525                        dalvikPss += mi.dalvikPss;
12526                        otherPss += mi.otherPss;
12527                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12528                            long mem = mi.getOtherPss(j);
12529                            miscPss[j] += mem;
12530                            otherPss -= mem;
12531                        }
12532                        oomPss[0] += myTotalPss;
12533                        if (oomProcs[0] == null) {
12534                            oomProcs[0] = new ArrayList<MemItem>();
12535                        }
12536                        oomProcs[0].add(pssItem);
12537                    }
12538                }
12539            }
12540
12541            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12542
12543            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12544            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12545            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12546            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12547                String label = Debug.MemoryInfo.getOtherLabel(j);
12548                catMems.add(new MemItem(label, label, miscPss[j], j));
12549            }
12550
12551            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12552            for (int j=0; j<oomPss.length; j++) {
12553                if (oomPss[j] != 0) {
12554                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12555                            : DUMP_MEM_OOM_LABEL[j];
12556                    MemItem item = new MemItem(label, label, oomPss[j],
12557                            DUMP_MEM_OOM_ADJ[j]);
12558                    item.subitems = oomProcs[j];
12559                    oomMems.add(item);
12560                }
12561            }
12562
12563            if (!brief && !oomOnly && !isCompact) {
12564                pw.println();
12565                pw.println("Total PSS by process:");
12566                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12567                pw.println();
12568            }
12569            if (!isCompact) {
12570                pw.println("Total PSS by OOM adjustment:");
12571            }
12572            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12573            if (!brief && !oomOnly) {
12574                PrintWriter out = categoryPw != null ? categoryPw : pw;
12575                if (!isCompact) {
12576                    out.println();
12577                    out.println("Total PSS by category:");
12578                }
12579                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12580            }
12581            if (!isCompact) {
12582                pw.println();
12583            }
12584            MemInfoReader memInfo = new MemInfoReader();
12585            memInfo.readMemInfo();
12586            if (!brief) {
12587                if (!isCompact) {
12588                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12589                    pw.print(" kB (status ");
12590                    switch (mLastMemoryLevel) {
12591                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12592                            pw.println("normal)");
12593                            break;
12594                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12595                            pw.println("moderate)");
12596                            break;
12597                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12598                            pw.println("low)");
12599                            break;
12600                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12601                            pw.println("critical)");
12602                            break;
12603                        default:
12604                            pw.print(mLastMemoryLevel);
12605                            pw.println(")");
12606                            break;
12607                    }
12608                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12609                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12610                            pw.print(cachedPss); pw.print(" cached pss + ");
12611                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12612                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12613                } else {
12614                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12615                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12616                            + memInfo.getFreeSizeKb()); pw.print(",");
12617                    pw.println(totalPss - cachedPss);
12618                }
12619            }
12620            if (!isCompact) {
12621                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12622                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12623                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12624                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12625                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12626                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12627                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12628                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12629                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12630                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12631                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12632            }
12633            if (!brief) {
12634                if (memInfo.getZramTotalSizeKb() != 0) {
12635                    if (!isCompact) {
12636                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12637                                pw.print(" kB physical used for ");
12638                                pw.print(memInfo.getSwapTotalSizeKb()
12639                                        - memInfo.getSwapFreeSizeKb());
12640                                pw.print(" kB in swap (");
12641                                pw.print(memInfo.getSwapTotalSizeKb());
12642                                pw.println(" kB total swap)");
12643                    } else {
12644                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12645                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12646                                pw.println(memInfo.getSwapFreeSizeKb());
12647                    }
12648                }
12649                final int[] SINGLE_LONG_FORMAT = new int[] {
12650                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12651                };
12652                long[] longOut = new long[1];
12653                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12654                        SINGLE_LONG_FORMAT, null, longOut, null);
12655                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12656                longOut[0] = 0;
12657                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12658                        SINGLE_LONG_FORMAT, null, longOut, null);
12659                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12660                longOut[0] = 0;
12661                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12662                        SINGLE_LONG_FORMAT, null, longOut, null);
12663                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12664                longOut[0] = 0;
12665                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12666                        SINGLE_LONG_FORMAT, null, longOut, null);
12667                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12668                if (!isCompact) {
12669                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12670                        pw.print("      KSM: "); pw.print(sharing);
12671                                pw.print(" kB saved from shared ");
12672                                pw.print(shared); pw.println(" kB");
12673                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12674                                pw.print(voltile); pw.println(" kB volatile");
12675                    }
12676                    pw.print("   Tuning: ");
12677                    pw.print(ActivityManager.staticGetMemoryClass());
12678                    pw.print(" (large ");
12679                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12680                    pw.print("), oom ");
12681                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12682                    pw.print(" kB");
12683                    pw.print(", restore limit ");
12684                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12685                    pw.print(" kB");
12686                    if (ActivityManager.isLowRamDeviceStatic()) {
12687                        pw.print(" (low-ram)");
12688                    }
12689                    if (ActivityManager.isHighEndGfx()) {
12690                        pw.print(" (high-end-gfx)");
12691                    }
12692                    pw.println();
12693                } else {
12694                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12695                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12696                    pw.println(voltile);
12697                    pw.print("tuning,");
12698                    pw.print(ActivityManager.staticGetMemoryClass());
12699                    pw.print(',');
12700                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12701                    pw.print(',');
12702                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12703                    if (ActivityManager.isLowRamDeviceStatic()) {
12704                        pw.print(",low-ram");
12705                    }
12706                    if (ActivityManager.isHighEndGfx()) {
12707                        pw.print(",high-end-gfx");
12708                    }
12709                    pw.println();
12710                }
12711            }
12712        }
12713    }
12714
12715    /**
12716     * Searches array of arguments for the specified string
12717     * @param args array of argument strings
12718     * @param value value to search for
12719     * @return true if the value is contained in the array
12720     */
12721    private static boolean scanArgs(String[] args, String value) {
12722        if (args != null) {
12723            for (String arg : args) {
12724                if (value.equals(arg)) {
12725                    return true;
12726                }
12727            }
12728        }
12729        return false;
12730    }
12731
12732    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12733            ContentProviderRecord cpr, boolean always) {
12734        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12735
12736        if (!inLaunching || always) {
12737            synchronized (cpr) {
12738                cpr.launchingApp = null;
12739                cpr.notifyAll();
12740            }
12741            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12742            String names[] = cpr.info.authority.split(";");
12743            for (int j = 0; j < names.length; j++) {
12744                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12745            }
12746        }
12747
12748        for (int i=0; i<cpr.connections.size(); i++) {
12749            ContentProviderConnection conn = cpr.connections.get(i);
12750            if (conn.waiting) {
12751                // If this connection is waiting for the provider, then we don't
12752                // need to mess with its process unless we are always removing
12753                // or for some reason the provider is not currently launching.
12754                if (inLaunching && !always) {
12755                    continue;
12756                }
12757            }
12758            ProcessRecord capp = conn.client;
12759            conn.dead = true;
12760            if (conn.stableCount > 0) {
12761                if (!capp.persistent && capp.thread != null
12762                        && capp.pid != 0
12763                        && capp.pid != MY_PID) {
12764                    killUnneededProcessLocked(capp, "depends on provider "
12765                            + cpr.name.flattenToShortString()
12766                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12767                }
12768            } else if (capp.thread != null && conn.provider.provider != null) {
12769                try {
12770                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12771                } catch (RemoteException e) {
12772                }
12773                // In the protocol here, we don't expect the client to correctly
12774                // clean up this connection, we'll just remove it.
12775                cpr.connections.remove(i);
12776                conn.client.conProviders.remove(conn);
12777            }
12778        }
12779
12780        if (inLaunching && always) {
12781            mLaunchingProviders.remove(cpr);
12782        }
12783        return inLaunching;
12784    }
12785
12786    /**
12787     * Main code for cleaning up a process when it has gone away.  This is
12788     * called both as a result of the process dying, or directly when stopping
12789     * a process when running in single process mode.
12790     */
12791    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12792            boolean restarting, boolean allowRestart, int index) {
12793        if (index >= 0) {
12794            removeLruProcessLocked(app);
12795            ProcessList.remove(app.pid);
12796        }
12797
12798        mProcessesToGc.remove(app);
12799        mPendingPssProcesses.remove(app);
12800
12801        // Dismiss any open dialogs.
12802        if (app.crashDialog != null && !app.forceCrashReport) {
12803            app.crashDialog.dismiss();
12804            app.crashDialog = null;
12805        }
12806        if (app.anrDialog != null) {
12807            app.anrDialog.dismiss();
12808            app.anrDialog = null;
12809        }
12810        if (app.waitDialog != null) {
12811            app.waitDialog.dismiss();
12812            app.waitDialog = null;
12813        }
12814
12815        app.crashing = false;
12816        app.notResponding = false;
12817
12818        app.resetPackageList(mProcessStats);
12819        app.unlinkDeathRecipient();
12820        app.makeInactive(mProcessStats);
12821        app.forcingToForeground = null;
12822        updateProcessForegroundLocked(app, false, false);
12823        app.foregroundActivities = false;
12824        app.hasShownUi = false;
12825        app.treatLikeActivity = false;
12826        app.hasAboveClient = false;
12827        app.hasClientActivities = false;
12828
12829        mServices.killServicesLocked(app, allowRestart);
12830
12831        boolean restart = false;
12832
12833        // Remove published content providers.
12834        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12835            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12836            final boolean always = app.bad || !allowRestart;
12837            if (removeDyingProviderLocked(app, cpr, always) || always) {
12838                // We left the provider in the launching list, need to
12839                // restart it.
12840                restart = true;
12841            }
12842
12843            cpr.provider = null;
12844            cpr.proc = null;
12845        }
12846        app.pubProviders.clear();
12847
12848        // Take care of any launching providers waiting for this process.
12849        if (checkAppInLaunchingProvidersLocked(app, false)) {
12850            restart = true;
12851        }
12852
12853        // Unregister from connected content providers.
12854        if (!app.conProviders.isEmpty()) {
12855            for (int i=0; i<app.conProviders.size(); i++) {
12856                ContentProviderConnection conn = app.conProviders.get(i);
12857                conn.provider.connections.remove(conn);
12858            }
12859            app.conProviders.clear();
12860        }
12861
12862        // At this point there may be remaining entries in mLaunchingProviders
12863        // where we were the only one waiting, so they are no longer of use.
12864        // Look for these and clean up if found.
12865        // XXX Commented out for now.  Trying to figure out a way to reproduce
12866        // the actual situation to identify what is actually going on.
12867        if (false) {
12868            for (int i=0; i<mLaunchingProviders.size(); i++) {
12869                ContentProviderRecord cpr = (ContentProviderRecord)
12870                        mLaunchingProviders.get(i);
12871                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12872                    synchronized (cpr) {
12873                        cpr.launchingApp = null;
12874                        cpr.notifyAll();
12875                    }
12876                }
12877            }
12878        }
12879
12880        skipCurrentReceiverLocked(app);
12881
12882        // Unregister any receivers.
12883        for (int i=app.receivers.size()-1; i>=0; i--) {
12884            removeReceiverLocked(app.receivers.valueAt(i));
12885        }
12886        app.receivers.clear();
12887
12888        // If the app is undergoing backup, tell the backup manager about it
12889        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12890            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12891                    + mBackupTarget.appInfo + " died during backup");
12892            try {
12893                IBackupManager bm = IBackupManager.Stub.asInterface(
12894                        ServiceManager.getService(Context.BACKUP_SERVICE));
12895                bm.agentDisconnected(app.info.packageName);
12896            } catch (RemoteException e) {
12897                // can't happen; backup manager is local
12898            }
12899        }
12900
12901        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12902            ProcessChangeItem item = mPendingProcessChanges.get(i);
12903            if (item.pid == app.pid) {
12904                mPendingProcessChanges.remove(i);
12905                mAvailProcessChanges.add(item);
12906            }
12907        }
12908        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12909
12910        // If the caller is restarting this app, then leave it in its
12911        // current lists and let the caller take care of it.
12912        if (restarting) {
12913            return;
12914        }
12915
12916        if (!app.persistent || app.isolated) {
12917            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12918                    "Removing non-persistent process during cleanup: " + app);
12919            mProcessNames.remove(app.processName, app.uid);
12920            mIsolatedProcesses.remove(app.uid);
12921            if (mHeavyWeightProcess == app) {
12922                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12923                        mHeavyWeightProcess.userId, 0));
12924                mHeavyWeightProcess = null;
12925            }
12926        } else if (!app.removed) {
12927            // This app is persistent, so we need to keep its record around.
12928            // If it is not already on the pending app list, add it there
12929            // and start a new process for it.
12930            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12931                mPersistentStartingProcesses.add(app);
12932                restart = true;
12933            }
12934        }
12935        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12936                "Clean-up removing on hold: " + app);
12937        mProcessesOnHold.remove(app);
12938
12939        if (app == mHomeProcess) {
12940            mHomeProcess = null;
12941        }
12942        if (app == mPreviousProcess) {
12943            mPreviousProcess = null;
12944        }
12945
12946        if (restart && !app.isolated) {
12947            // We have components that still need to be running in the
12948            // process, so re-launch it.
12949            mProcessNames.put(app.processName, app.uid, app);
12950            startProcessLocked(app, "restart", app.processName);
12951        } else if (app.pid > 0 && app.pid != MY_PID) {
12952            // Goodbye!
12953            boolean removed;
12954            synchronized (mPidsSelfLocked) {
12955                mPidsSelfLocked.remove(app.pid);
12956                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12957            }
12958            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12959                    app.processName, app.info.uid);
12960            if (app.isolated) {
12961                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12962            }
12963            app.setPid(0);
12964        }
12965    }
12966
12967    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12968        // Look through the content providers we are waiting to have launched,
12969        // and if any run in this process then either schedule a restart of
12970        // the process or kill the client waiting for it if this process has
12971        // gone bad.
12972        int NL = mLaunchingProviders.size();
12973        boolean restart = false;
12974        for (int i=0; i<NL; i++) {
12975            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12976            if (cpr.launchingApp == app) {
12977                if (!alwaysBad && !app.bad) {
12978                    restart = true;
12979                } else {
12980                    removeDyingProviderLocked(app, cpr, true);
12981                    // cpr should have been removed from mLaunchingProviders
12982                    NL = mLaunchingProviders.size();
12983                    i--;
12984                }
12985            }
12986        }
12987        return restart;
12988    }
12989
12990    // =========================================================
12991    // SERVICES
12992    // =========================================================
12993
12994    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12995            int flags) {
12996        enforceNotIsolatedCaller("getServices");
12997        synchronized (this) {
12998            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12999        }
13000    }
13001
13002    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13003        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13004        synchronized (this) {
13005            return mServices.getRunningServiceControlPanelLocked(name);
13006        }
13007    }
13008
13009    public ComponentName startService(IApplicationThread caller, Intent service,
13010            String resolvedType, int userId) {
13011        enforceNotIsolatedCaller("startService");
13012        // Refuse possible leaked file descriptors
13013        if (service != null && service.hasFileDescriptors() == true) {
13014            throw new IllegalArgumentException("File descriptors passed in Intent");
13015        }
13016
13017        if (DEBUG_SERVICE)
13018            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13019        synchronized(this) {
13020            final int callingPid = Binder.getCallingPid();
13021            final int callingUid = Binder.getCallingUid();
13022            final long origId = Binder.clearCallingIdentity();
13023            ComponentName res = mServices.startServiceLocked(caller, service,
13024                    resolvedType, callingPid, callingUid, userId);
13025            Binder.restoreCallingIdentity(origId);
13026            return res;
13027        }
13028    }
13029
13030    ComponentName startServiceInPackage(int uid,
13031            Intent service, String resolvedType, int userId) {
13032        synchronized(this) {
13033            if (DEBUG_SERVICE)
13034                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13035            final long origId = Binder.clearCallingIdentity();
13036            ComponentName res = mServices.startServiceLocked(null, service,
13037                    resolvedType, -1, uid, userId);
13038            Binder.restoreCallingIdentity(origId);
13039            return res;
13040        }
13041    }
13042
13043    public int stopService(IApplicationThread caller, Intent service,
13044            String resolvedType, int userId) {
13045        enforceNotIsolatedCaller("stopService");
13046        // Refuse possible leaked file descriptors
13047        if (service != null && service.hasFileDescriptors() == true) {
13048            throw new IllegalArgumentException("File descriptors passed in Intent");
13049        }
13050
13051        synchronized(this) {
13052            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13053        }
13054    }
13055
13056    public IBinder peekService(Intent service, String resolvedType) {
13057        enforceNotIsolatedCaller("peekService");
13058        // Refuse possible leaked file descriptors
13059        if (service != null && service.hasFileDescriptors() == true) {
13060            throw new IllegalArgumentException("File descriptors passed in Intent");
13061        }
13062        synchronized(this) {
13063            return mServices.peekServiceLocked(service, resolvedType);
13064        }
13065    }
13066
13067    public boolean stopServiceToken(ComponentName className, IBinder token,
13068            int startId) {
13069        synchronized(this) {
13070            return mServices.stopServiceTokenLocked(className, token, startId);
13071        }
13072    }
13073
13074    public void setServiceForeground(ComponentName className, IBinder token,
13075            int id, Notification notification, boolean removeNotification) {
13076        synchronized(this) {
13077            mServices.setServiceForegroundLocked(className, token, id, notification,
13078                    removeNotification);
13079        }
13080    }
13081
13082    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13083            boolean requireFull, String name, String callerPackage) {
13084        final int callingUserId = UserHandle.getUserId(callingUid);
13085        if (callingUserId != userId) {
13086            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13087                if ((requireFull || checkComponentPermission(
13088                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13089                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13090                        && checkComponentPermission(
13091                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13092                                callingPid, callingUid, -1, true)
13093                                != PackageManager.PERMISSION_GRANTED) {
13094                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13095                        // In this case, they would like to just execute as their
13096                        // owner user instead of failing.
13097                        userId = callingUserId;
13098                    } else {
13099                        StringBuilder builder = new StringBuilder(128);
13100                        builder.append("Permission Denial: ");
13101                        builder.append(name);
13102                        if (callerPackage != null) {
13103                            builder.append(" from ");
13104                            builder.append(callerPackage);
13105                        }
13106                        builder.append(" asks to run as user ");
13107                        builder.append(userId);
13108                        builder.append(" but is calling from user ");
13109                        builder.append(UserHandle.getUserId(callingUid));
13110                        builder.append("; this requires ");
13111                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13112                        if (!requireFull) {
13113                            builder.append(" or ");
13114                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13115                        }
13116                        String msg = builder.toString();
13117                        Slog.w(TAG, msg);
13118                        throw new SecurityException(msg);
13119                    }
13120                }
13121            }
13122            if (userId == UserHandle.USER_CURRENT
13123                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13124                // Note that we may be accessing this outside of a lock...
13125                // shouldn't be a big deal, if this is being called outside
13126                // of a locked context there is intrinsically a race with
13127                // the value the caller will receive and someone else changing it.
13128                userId = mCurrentUserId;
13129            }
13130            if (!allowAll && userId < 0) {
13131                throw new IllegalArgumentException(
13132                        "Call does not support special user #" + userId);
13133            }
13134        }
13135        return userId;
13136    }
13137
13138    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13139            String className, int flags) {
13140        boolean result = false;
13141        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13142            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13143                if (ActivityManager.checkUidPermission(
13144                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13145                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13146                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13147                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13148                            + " requests FLAG_SINGLE_USER, but app does not hold "
13149                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13150                    Slog.w(TAG, msg);
13151                    throw new SecurityException(msg);
13152                }
13153                result = true;
13154            }
13155        } else if (componentProcessName == aInfo.packageName) {
13156            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13157        } else if ("system".equals(componentProcessName)) {
13158            result = true;
13159        }
13160        if (DEBUG_MU) {
13161            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13162                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13163        }
13164        return result;
13165    }
13166
13167    public int bindService(IApplicationThread caller, IBinder token,
13168            Intent service, String resolvedType,
13169            IServiceConnection connection, int flags, int userId) {
13170        enforceNotIsolatedCaller("bindService");
13171        // Refuse possible leaked file descriptors
13172        if (service != null && service.hasFileDescriptors() == true) {
13173            throw new IllegalArgumentException("File descriptors passed in Intent");
13174        }
13175
13176        synchronized(this) {
13177            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13178                    connection, flags, userId);
13179        }
13180    }
13181
13182    public boolean unbindService(IServiceConnection connection) {
13183        synchronized (this) {
13184            return mServices.unbindServiceLocked(connection);
13185        }
13186    }
13187
13188    public void publishService(IBinder token, Intent intent, IBinder service) {
13189        // Refuse possible leaked file descriptors
13190        if (intent != null && intent.hasFileDescriptors() == true) {
13191            throw new IllegalArgumentException("File descriptors passed in Intent");
13192        }
13193
13194        synchronized(this) {
13195            if (!(token instanceof ServiceRecord)) {
13196                throw new IllegalArgumentException("Invalid service token");
13197            }
13198            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13199        }
13200    }
13201
13202    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13203        // Refuse possible leaked file descriptors
13204        if (intent != null && intent.hasFileDescriptors() == true) {
13205            throw new IllegalArgumentException("File descriptors passed in Intent");
13206        }
13207
13208        synchronized(this) {
13209            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13210        }
13211    }
13212
13213    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13214        synchronized(this) {
13215            if (!(token instanceof ServiceRecord)) {
13216                throw new IllegalArgumentException("Invalid service token");
13217            }
13218            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13219        }
13220    }
13221
13222    // =========================================================
13223    // BACKUP AND RESTORE
13224    // =========================================================
13225
13226    // Cause the target app to be launched if necessary and its backup agent
13227    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13228    // activity manager to announce its creation.
13229    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13230        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13231        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13232
13233        synchronized(this) {
13234            // !!! TODO: currently no check here that we're already bound
13235            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13236            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13237            synchronized (stats) {
13238                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13239            }
13240
13241            // Backup agent is now in use, its package can't be stopped.
13242            try {
13243                AppGlobals.getPackageManager().setPackageStoppedState(
13244                        app.packageName, false, UserHandle.getUserId(app.uid));
13245            } catch (RemoteException e) {
13246            } catch (IllegalArgumentException e) {
13247                Slog.w(TAG, "Failed trying to unstop package "
13248                        + app.packageName + ": " + e);
13249            }
13250
13251            BackupRecord r = new BackupRecord(ss, app, backupMode);
13252            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13253                    ? new ComponentName(app.packageName, app.backupAgentName)
13254                    : new ComponentName("android", "FullBackupAgent");
13255            // startProcessLocked() returns existing proc's record if it's already running
13256            ProcessRecord proc = startProcessLocked(app.processName, app,
13257                    false, 0, "backup", hostingName, false, false, false);
13258            if (proc == null) {
13259                Slog.e(TAG, "Unable to start backup agent process " + r);
13260                return false;
13261            }
13262
13263            r.app = proc;
13264            mBackupTarget = r;
13265            mBackupAppName = app.packageName;
13266
13267            // Try not to kill the process during backup
13268            updateOomAdjLocked(proc);
13269
13270            // If the process is already attached, schedule the creation of the backup agent now.
13271            // If it is not yet live, this will be done when it attaches to the framework.
13272            if (proc.thread != null) {
13273                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13274                try {
13275                    proc.thread.scheduleCreateBackupAgent(app,
13276                            compatibilityInfoForPackageLocked(app), backupMode);
13277                } catch (RemoteException e) {
13278                    // Will time out on the backup manager side
13279                }
13280            } else {
13281                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13282            }
13283            // Invariants: at this point, the target app process exists and the application
13284            // is either already running or in the process of coming up.  mBackupTarget and
13285            // mBackupAppName describe the app, so that when it binds back to the AM we
13286            // know that it's scheduled for a backup-agent operation.
13287        }
13288
13289        return true;
13290    }
13291
13292    @Override
13293    public void clearPendingBackup() {
13294        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13295        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13296
13297        synchronized (this) {
13298            mBackupTarget = null;
13299            mBackupAppName = null;
13300        }
13301    }
13302
13303    // A backup agent has just come up
13304    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13305        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13306                + " = " + agent);
13307
13308        synchronized(this) {
13309            if (!agentPackageName.equals(mBackupAppName)) {
13310                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13311                return;
13312            }
13313        }
13314
13315        long oldIdent = Binder.clearCallingIdentity();
13316        try {
13317            IBackupManager bm = IBackupManager.Stub.asInterface(
13318                    ServiceManager.getService(Context.BACKUP_SERVICE));
13319            bm.agentConnected(agentPackageName, agent);
13320        } catch (RemoteException e) {
13321            // can't happen; the backup manager service is local
13322        } catch (Exception e) {
13323            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13324            e.printStackTrace();
13325        } finally {
13326            Binder.restoreCallingIdentity(oldIdent);
13327        }
13328    }
13329
13330    // done with this agent
13331    public void unbindBackupAgent(ApplicationInfo appInfo) {
13332        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13333        if (appInfo == null) {
13334            Slog.w(TAG, "unbind backup agent for null app");
13335            return;
13336        }
13337
13338        synchronized(this) {
13339            try {
13340                if (mBackupAppName == null) {
13341                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13342                    return;
13343                }
13344
13345                if (!mBackupAppName.equals(appInfo.packageName)) {
13346                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13347                    return;
13348                }
13349
13350                // Not backing this app up any more; reset its OOM adjustment
13351                final ProcessRecord proc = mBackupTarget.app;
13352                updateOomAdjLocked(proc);
13353
13354                // If the app crashed during backup, 'thread' will be null here
13355                if (proc.thread != null) {
13356                    try {
13357                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13358                                compatibilityInfoForPackageLocked(appInfo));
13359                    } catch (Exception e) {
13360                        Slog.e(TAG, "Exception when unbinding backup agent:");
13361                        e.printStackTrace();
13362                    }
13363                }
13364            } finally {
13365                mBackupTarget = null;
13366                mBackupAppName = null;
13367            }
13368        }
13369    }
13370    // =========================================================
13371    // BROADCASTS
13372    // =========================================================
13373
13374    private final List getStickiesLocked(String action, IntentFilter filter,
13375            List cur, int userId) {
13376        final ContentResolver resolver = mContext.getContentResolver();
13377        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13378        if (stickies == null) {
13379            return cur;
13380        }
13381        final ArrayList<Intent> list = stickies.get(action);
13382        if (list == null) {
13383            return cur;
13384        }
13385        int N = list.size();
13386        for (int i=0; i<N; i++) {
13387            Intent intent = list.get(i);
13388            if (filter.match(resolver, intent, true, TAG) >= 0) {
13389                if (cur == null) {
13390                    cur = new ArrayList<Intent>();
13391                }
13392                cur.add(intent);
13393            }
13394        }
13395        return cur;
13396    }
13397
13398    boolean isPendingBroadcastProcessLocked(int pid) {
13399        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13400                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13401    }
13402
13403    void skipPendingBroadcastLocked(int pid) {
13404            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13405            for (BroadcastQueue queue : mBroadcastQueues) {
13406                queue.skipPendingBroadcastLocked(pid);
13407            }
13408    }
13409
13410    // The app just attached; send any pending broadcasts that it should receive
13411    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13412        boolean didSomething = false;
13413        for (BroadcastQueue queue : mBroadcastQueues) {
13414            didSomething |= queue.sendPendingBroadcastsLocked(app);
13415        }
13416        return didSomething;
13417    }
13418
13419    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13420            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13421        enforceNotIsolatedCaller("registerReceiver");
13422        int callingUid;
13423        int callingPid;
13424        synchronized(this) {
13425            ProcessRecord callerApp = null;
13426            if (caller != null) {
13427                callerApp = getRecordForAppLocked(caller);
13428                if (callerApp == null) {
13429                    throw new SecurityException(
13430                            "Unable to find app for caller " + caller
13431                            + " (pid=" + Binder.getCallingPid()
13432                            + ") when registering receiver " + receiver);
13433                }
13434                if (callerApp.info.uid != Process.SYSTEM_UID &&
13435                        !callerApp.pkgList.containsKey(callerPackage) &&
13436                        !"android".equals(callerPackage)) {
13437                    throw new SecurityException("Given caller package " + callerPackage
13438                            + " is not running in process " + callerApp);
13439                }
13440                callingUid = callerApp.info.uid;
13441                callingPid = callerApp.pid;
13442            } else {
13443                callerPackage = null;
13444                callingUid = Binder.getCallingUid();
13445                callingPid = Binder.getCallingPid();
13446            }
13447
13448            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13449                    true, true, "registerReceiver", callerPackage);
13450
13451            List allSticky = null;
13452
13453            // Look for any matching sticky broadcasts...
13454            Iterator actions = filter.actionsIterator();
13455            if (actions != null) {
13456                while (actions.hasNext()) {
13457                    String action = (String)actions.next();
13458                    allSticky = getStickiesLocked(action, filter, allSticky,
13459                            UserHandle.USER_ALL);
13460                    allSticky = getStickiesLocked(action, filter, allSticky,
13461                            UserHandle.getUserId(callingUid));
13462                }
13463            } else {
13464                allSticky = getStickiesLocked(null, filter, allSticky,
13465                        UserHandle.USER_ALL);
13466                allSticky = getStickiesLocked(null, filter, allSticky,
13467                        UserHandle.getUserId(callingUid));
13468            }
13469
13470            // The first sticky in the list is returned directly back to
13471            // the client.
13472            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13473
13474            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13475                    + ": " + sticky);
13476
13477            if (receiver == null) {
13478                return sticky;
13479            }
13480
13481            ReceiverList rl
13482                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13483            if (rl == null) {
13484                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13485                        userId, receiver);
13486                if (rl.app != null) {
13487                    rl.app.receivers.add(rl);
13488                } else {
13489                    try {
13490                        receiver.asBinder().linkToDeath(rl, 0);
13491                    } catch (RemoteException e) {
13492                        return sticky;
13493                    }
13494                    rl.linkedToDeath = true;
13495                }
13496                mRegisteredReceivers.put(receiver.asBinder(), rl);
13497            } else if (rl.uid != callingUid) {
13498                throw new IllegalArgumentException(
13499                        "Receiver requested to register for uid " + callingUid
13500                        + " was previously registered for uid " + rl.uid);
13501            } else if (rl.pid != callingPid) {
13502                throw new IllegalArgumentException(
13503                        "Receiver requested to register for pid " + callingPid
13504                        + " was previously registered for pid " + rl.pid);
13505            } else if (rl.userId != userId) {
13506                throw new IllegalArgumentException(
13507                        "Receiver requested to register for user " + userId
13508                        + " was previously registered for user " + rl.userId);
13509            }
13510            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13511                    permission, callingUid, userId);
13512            rl.add(bf);
13513            if (!bf.debugCheck()) {
13514                Slog.w(TAG, "==> For Dynamic broadast");
13515            }
13516            mReceiverResolver.addFilter(bf);
13517
13518            // Enqueue broadcasts for all existing stickies that match
13519            // this filter.
13520            if (allSticky != null) {
13521                ArrayList receivers = new ArrayList();
13522                receivers.add(bf);
13523
13524                int N = allSticky.size();
13525                for (int i=0; i<N; i++) {
13526                    Intent intent = (Intent)allSticky.get(i);
13527                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13528                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13529                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13530                            null, null, false, true, true, -1);
13531                    queue.enqueueParallelBroadcastLocked(r);
13532                    queue.scheduleBroadcastsLocked();
13533                }
13534            }
13535
13536            return sticky;
13537        }
13538    }
13539
13540    public void unregisterReceiver(IIntentReceiver receiver) {
13541        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13542
13543        final long origId = Binder.clearCallingIdentity();
13544        try {
13545            boolean doTrim = false;
13546
13547            synchronized(this) {
13548                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13549                if (rl != null) {
13550                    if (rl.curBroadcast != null) {
13551                        BroadcastRecord r = rl.curBroadcast;
13552                        final boolean doNext = finishReceiverLocked(
13553                                receiver.asBinder(), r.resultCode, r.resultData,
13554                                r.resultExtras, r.resultAbort);
13555                        if (doNext) {
13556                            doTrim = true;
13557                            r.queue.processNextBroadcast(false);
13558                        }
13559                    }
13560
13561                    if (rl.app != null) {
13562                        rl.app.receivers.remove(rl);
13563                    }
13564                    removeReceiverLocked(rl);
13565                    if (rl.linkedToDeath) {
13566                        rl.linkedToDeath = false;
13567                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13568                    }
13569                }
13570            }
13571
13572            // If we actually concluded any broadcasts, we might now be able
13573            // to trim the recipients' apps from our working set
13574            if (doTrim) {
13575                trimApplications();
13576                return;
13577            }
13578
13579        } finally {
13580            Binder.restoreCallingIdentity(origId);
13581        }
13582    }
13583
13584    void removeReceiverLocked(ReceiverList rl) {
13585        mRegisteredReceivers.remove(rl.receiver.asBinder());
13586        int N = rl.size();
13587        for (int i=0; i<N; i++) {
13588            mReceiverResolver.removeFilter(rl.get(i));
13589        }
13590    }
13591
13592    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13593        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13594            ProcessRecord r = mLruProcesses.get(i);
13595            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13596                try {
13597                    r.thread.dispatchPackageBroadcast(cmd, packages);
13598                } catch (RemoteException ex) {
13599                }
13600            }
13601        }
13602    }
13603
13604    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13605            int[] users) {
13606        List<ResolveInfo> receivers = null;
13607        try {
13608            HashSet<ComponentName> singleUserReceivers = null;
13609            boolean scannedFirstReceivers = false;
13610            for (int user : users) {
13611                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13612                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13613                if (user != 0 && newReceivers != null) {
13614                    // If this is not the primary user, we need to check for
13615                    // any receivers that should be filtered out.
13616                    for (int i=0; i<newReceivers.size(); i++) {
13617                        ResolveInfo ri = newReceivers.get(i);
13618                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13619                            newReceivers.remove(i);
13620                            i--;
13621                        }
13622                    }
13623                }
13624                if (newReceivers != null && newReceivers.size() == 0) {
13625                    newReceivers = null;
13626                }
13627                if (receivers == null) {
13628                    receivers = newReceivers;
13629                } else if (newReceivers != null) {
13630                    // We need to concatenate the additional receivers
13631                    // found with what we have do far.  This would be easy,
13632                    // but we also need to de-dup any receivers that are
13633                    // singleUser.
13634                    if (!scannedFirstReceivers) {
13635                        // Collect any single user receivers we had already retrieved.
13636                        scannedFirstReceivers = true;
13637                        for (int i=0; i<receivers.size(); i++) {
13638                            ResolveInfo ri = receivers.get(i);
13639                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13640                                ComponentName cn = new ComponentName(
13641                                        ri.activityInfo.packageName, ri.activityInfo.name);
13642                                if (singleUserReceivers == null) {
13643                                    singleUserReceivers = new HashSet<ComponentName>();
13644                                }
13645                                singleUserReceivers.add(cn);
13646                            }
13647                        }
13648                    }
13649                    // Add the new results to the existing results, tracking
13650                    // and de-dupping single user receivers.
13651                    for (int i=0; i<newReceivers.size(); i++) {
13652                        ResolveInfo ri = newReceivers.get(i);
13653                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13654                            ComponentName cn = new ComponentName(
13655                                    ri.activityInfo.packageName, ri.activityInfo.name);
13656                            if (singleUserReceivers == null) {
13657                                singleUserReceivers = new HashSet<ComponentName>();
13658                            }
13659                            if (!singleUserReceivers.contains(cn)) {
13660                                singleUserReceivers.add(cn);
13661                                receivers.add(ri);
13662                            }
13663                        } else {
13664                            receivers.add(ri);
13665                        }
13666                    }
13667                }
13668            }
13669        } catch (RemoteException ex) {
13670            // pm is in same process, this will never happen.
13671        }
13672        return receivers;
13673    }
13674
13675    private final int broadcastIntentLocked(ProcessRecord callerApp,
13676            String callerPackage, Intent intent, String resolvedType,
13677            IIntentReceiver resultTo, int resultCode, String resultData,
13678            Bundle map, String requiredPermission, int appOp,
13679            boolean ordered, boolean sticky, int callingPid, int callingUid,
13680            int userId) {
13681        intent = new Intent(intent);
13682
13683        // By default broadcasts do not go to stopped apps.
13684        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13685
13686        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13687            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13688            + " ordered=" + ordered + " userid=" + userId);
13689        if ((resultTo != null) && !ordered) {
13690            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13691        }
13692
13693        userId = handleIncomingUser(callingPid, callingUid, userId,
13694                true, false, "broadcast", callerPackage);
13695
13696        // Make sure that the user who is receiving this broadcast is started.
13697        // If not, we will just skip it.
13698        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13699            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13700                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13701                Slog.w(TAG, "Skipping broadcast of " + intent
13702                        + ": user " + userId + " is stopped");
13703                return ActivityManager.BROADCAST_SUCCESS;
13704            }
13705        }
13706
13707        /*
13708         * Prevent non-system code (defined here to be non-persistent
13709         * processes) from sending protected broadcasts.
13710         */
13711        int callingAppId = UserHandle.getAppId(callingUid);
13712        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13713            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13714            callingUid == 0) {
13715            // Always okay.
13716        } else if (callerApp == null || !callerApp.persistent) {
13717            try {
13718                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13719                        intent.getAction())) {
13720                    String msg = "Permission Denial: not allowed to send broadcast "
13721                            + intent.getAction() + " from pid="
13722                            + callingPid + ", uid=" + callingUid;
13723                    Slog.w(TAG, msg);
13724                    throw new SecurityException(msg);
13725                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13726                    // Special case for compatibility: we don't want apps to send this,
13727                    // but historically it has not been protected and apps may be using it
13728                    // to poke their own app widget.  So, instead of making it protected,
13729                    // just limit it to the caller.
13730                    if (callerApp == null) {
13731                        String msg = "Permission Denial: not allowed to send broadcast "
13732                                + intent.getAction() + " from unknown caller.";
13733                        Slog.w(TAG, msg);
13734                        throw new SecurityException(msg);
13735                    } else if (intent.getComponent() != null) {
13736                        // They are good enough to send to an explicit component...  verify
13737                        // it is being sent to the calling app.
13738                        if (!intent.getComponent().getPackageName().equals(
13739                                callerApp.info.packageName)) {
13740                            String msg = "Permission Denial: not allowed to send broadcast "
13741                                    + intent.getAction() + " to "
13742                                    + intent.getComponent().getPackageName() + " from "
13743                                    + callerApp.info.packageName;
13744                            Slog.w(TAG, msg);
13745                            throw new SecurityException(msg);
13746                        }
13747                    } else {
13748                        // Limit broadcast to their own package.
13749                        intent.setPackage(callerApp.info.packageName);
13750                    }
13751                }
13752            } catch (RemoteException e) {
13753                Slog.w(TAG, "Remote exception", e);
13754                return ActivityManager.BROADCAST_SUCCESS;
13755            }
13756        }
13757
13758        // Handle special intents: if this broadcast is from the package
13759        // manager about a package being removed, we need to remove all of
13760        // its activities from the history stack.
13761        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13762                intent.getAction());
13763        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13764                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13765                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13766                || uidRemoved) {
13767            if (checkComponentPermission(
13768                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13769                    callingPid, callingUid, -1, true)
13770                    == PackageManager.PERMISSION_GRANTED) {
13771                if (uidRemoved) {
13772                    final Bundle intentExtras = intent.getExtras();
13773                    final int uid = intentExtras != null
13774                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13775                    if (uid >= 0) {
13776                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13777                        synchronized (bs) {
13778                            bs.removeUidStatsLocked(uid);
13779                        }
13780                        mAppOpsService.uidRemoved(uid);
13781                    }
13782                } else {
13783                    // If resources are unavailable just force stop all
13784                    // those packages and flush the attribute cache as well.
13785                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13786                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13787                        if (list != null && (list.length > 0)) {
13788                            for (String pkg : list) {
13789                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13790                                        "storage unmount");
13791                            }
13792                            sendPackageBroadcastLocked(
13793                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13794                        }
13795                    } else {
13796                        Uri data = intent.getData();
13797                        String ssp;
13798                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13799                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13800                                    intent.getAction());
13801                            boolean fullUninstall = removed &&
13802                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13803                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13804                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13805                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13806                                        false, fullUninstall, userId,
13807                                        removed ? "pkg removed" : "pkg changed");
13808                            }
13809                            if (removed) {
13810                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13811                                        new String[] {ssp}, userId);
13812                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13813                                    mAppOpsService.packageRemoved(
13814                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13815
13816                                    // Remove all permissions granted from/to this package
13817                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13818                                }
13819                            }
13820                        }
13821                    }
13822                }
13823            } else {
13824                String msg = "Permission Denial: " + intent.getAction()
13825                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13826                        + ", uid=" + callingUid + ")"
13827                        + " requires "
13828                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13829                Slog.w(TAG, msg);
13830                throw new SecurityException(msg);
13831            }
13832
13833        // Special case for adding a package: by default turn on compatibility
13834        // mode.
13835        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13836            Uri data = intent.getData();
13837            String ssp;
13838            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13839                mCompatModePackages.handlePackageAddedLocked(ssp,
13840                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13841            }
13842        }
13843
13844        /*
13845         * If this is the time zone changed action, queue up a message that will reset the timezone
13846         * of all currently running processes. This message will get queued up before the broadcast
13847         * happens.
13848         */
13849        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13850            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13851        }
13852
13853        /*
13854         * If the user set the time, let all running processes know.
13855         */
13856        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13857            final int is24Hour = intent.getBooleanExtra(
13858                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13859            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13860        }
13861
13862        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13863            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13864        }
13865
13866        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13867            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13868            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13869        }
13870
13871        // Add to the sticky list if requested.
13872        if (sticky) {
13873            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13874                    callingPid, callingUid)
13875                    != PackageManager.PERMISSION_GRANTED) {
13876                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13877                        + callingPid + ", uid=" + callingUid
13878                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13879                Slog.w(TAG, msg);
13880                throw new SecurityException(msg);
13881            }
13882            if (requiredPermission != null) {
13883                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13884                        + " and enforce permission " + requiredPermission);
13885                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13886            }
13887            if (intent.getComponent() != null) {
13888                throw new SecurityException(
13889                        "Sticky broadcasts can't target a specific component");
13890            }
13891            // We use userId directly here, since the "all" target is maintained
13892            // as a separate set of sticky broadcasts.
13893            if (userId != UserHandle.USER_ALL) {
13894                // But first, if this is not a broadcast to all users, then
13895                // make sure it doesn't conflict with an existing broadcast to
13896                // all users.
13897                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13898                        UserHandle.USER_ALL);
13899                if (stickies != null) {
13900                    ArrayList<Intent> list = stickies.get(intent.getAction());
13901                    if (list != null) {
13902                        int N = list.size();
13903                        int i;
13904                        for (i=0; i<N; i++) {
13905                            if (intent.filterEquals(list.get(i))) {
13906                                throw new IllegalArgumentException(
13907                                        "Sticky broadcast " + intent + " for user "
13908                                        + userId + " conflicts with existing global broadcast");
13909                            }
13910                        }
13911                    }
13912                }
13913            }
13914            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13915            if (stickies == null) {
13916                stickies = new ArrayMap<String, ArrayList<Intent>>();
13917                mStickyBroadcasts.put(userId, stickies);
13918            }
13919            ArrayList<Intent> list = stickies.get(intent.getAction());
13920            if (list == null) {
13921                list = new ArrayList<Intent>();
13922                stickies.put(intent.getAction(), list);
13923            }
13924            int N = list.size();
13925            int i;
13926            for (i=0; i<N; i++) {
13927                if (intent.filterEquals(list.get(i))) {
13928                    // This sticky already exists, replace it.
13929                    list.set(i, new Intent(intent));
13930                    break;
13931                }
13932            }
13933            if (i >= N) {
13934                list.add(new Intent(intent));
13935            }
13936        }
13937
13938        int[] users;
13939        if (userId == UserHandle.USER_ALL) {
13940            // Caller wants broadcast to go to all started users.
13941            users = mStartedUserArray;
13942        } else {
13943            // Caller wants broadcast to go to one specific user.
13944            users = new int[] {userId};
13945        }
13946
13947        // Figure out who all will receive this broadcast.
13948        List receivers = null;
13949        List<BroadcastFilter> registeredReceivers = null;
13950        // Need to resolve the intent to interested receivers...
13951        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13952                 == 0) {
13953            receivers = collectReceiverComponents(intent, resolvedType, users);
13954        }
13955        if (intent.getComponent() == null) {
13956            registeredReceivers = mReceiverResolver.queryIntent(intent,
13957                    resolvedType, false, userId);
13958        }
13959
13960        final boolean replacePending =
13961                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13962
13963        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13964                + " replacePending=" + replacePending);
13965
13966        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13967        if (!ordered && NR > 0) {
13968            // If we are not serializing this broadcast, then send the
13969            // registered receivers separately so they don't wait for the
13970            // components to be launched.
13971            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13972            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13973                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13974                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13975                    ordered, sticky, false, userId);
13976            if (DEBUG_BROADCAST) Slog.v(
13977                    TAG, "Enqueueing parallel broadcast " + r);
13978            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13979            if (!replaced) {
13980                queue.enqueueParallelBroadcastLocked(r);
13981                queue.scheduleBroadcastsLocked();
13982            }
13983            registeredReceivers = null;
13984            NR = 0;
13985        }
13986
13987        // Merge into one list.
13988        int ir = 0;
13989        if (receivers != null) {
13990            // A special case for PACKAGE_ADDED: do not allow the package
13991            // being added to see this broadcast.  This prevents them from
13992            // using this as a back door to get run as soon as they are
13993            // installed.  Maybe in the future we want to have a special install
13994            // broadcast or such for apps, but we'd like to deliberately make
13995            // this decision.
13996            String skipPackages[] = null;
13997            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13998                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13999                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14000                Uri data = intent.getData();
14001                if (data != null) {
14002                    String pkgName = data.getSchemeSpecificPart();
14003                    if (pkgName != null) {
14004                        skipPackages = new String[] { pkgName };
14005                    }
14006                }
14007            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14008                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14009            }
14010            if (skipPackages != null && (skipPackages.length > 0)) {
14011                for (String skipPackage : skipPackages) {
14012                    if (skipPackage != null) {
14013                        int NT = receivers.size();
14014                        for (int it=0; it<NT; it++) {
14015                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14016                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14017                                receivers.remove(it);
14018                                it--;
14019                                NT--;
14020                            }
14021                        }
14022                    }
14023                }
14024            }
14025
14026            int NT = receivers != null ? receivers.size() : 0;
14027            int it = 0;
14028            ResolveInfo curt = null;
14029            BroadcastFilter curr = null;
14030            while (it < NT && ir < NR) {
14031                if (curt == null) {
14032                    curt = (ResolveInfo)receivers.get(it);
14033                }
14034                if (curr == null) {
14035                    curr = registeredReceivers.get(ir);
14036                }
14037                if (curr.getPriority() >= curt.priority) {
14038                    // Insert this broadcast record into the final list.
14039                    receivers.add(it, curr);
14040                    ir++;
14041                    curr = null;
14042                    it++;
14043                    NT++;
14044                } else {
14045                    // Skip to the next ResolveInfo in the final list.
14046                    it++;
14047                    curt = null;
14048                }
14049            }
14050        }
14051        while (ir < NR) {
14052            if (receivers == null) {
14053                receivers = new ArrayList();
14054            }
14055            receivers.add(registeredReceivers.get(ir));
14056            ir++;
14057        }
14058
14059        if ((receivers != null && receivers.size() > 0)
14060                || resultTo != null) {
14061            BroadcastQueue queue = broadcastQueueForIntent(intent);
14062            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14063                    callerPackage, callingPid, callingUid, resolvedType,
14064                    requiredPermission, appOp, receivers, resultTo, resultCode,
14065                    resultData, map, ordered, sticky, false, userId);
14066            if (DEBUG_BROADCAST) Slog.v(
14067                    TAG, "Enqueueing ordered broadcast " + r
14068                    + ": prev had " + queue.mOrderedBroadcasts.size());
14069            if (DEBUG_BROADCAST) {
14070                int seq = r.intent.getIntExtra("seq", -1);
14071                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14072            }
14073            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14074            if (!replaced) {
14075                queue.enqueueOrderedBroadcastLocked(r);
14076                queue.scheduleBroadcastsLocked();
14077            }
14078        }
14079
14080        return ActivityManager.BROADCAST_SUCCESS;
14081    }
14082
14083    final Intent verifyBroadcastLocked(Intent intent) {
14084        // Refuse possible leaked file descriptors
14085        if (intent != null && intent.hasFileDescriptors() == true) {
14086            throw new IllegalArgumentException("File descriptors passed in Intent");
14087        }
14088
14089        int flags = intent.getFlags();
14090
14091        if (!mProcessesReady) {
14092            // if the caller really truly claims to know what they're doing, go
14093            // ahead and allow the broadcast without launching any receivers
14094            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14095                intent = new Intent(intent);
14096                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14097            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14098                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14099                        + " before boot completion");
14100                throw new IllegalStateException("Cannot broadcast before boot completed");
14101            }
14102        }
14103
14104        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14105            throw new IllegalArgumentException(
14106                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14107        }
14108
14109        return intent;
14110    }
14111
14112    public final int broadcastIntent(IApplicationThread caller,
14113            Intent intent, String resolvedType, IIntentReceiver resultTo,
14114            int resultCode, String resultData, Bundle map,
14115            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14116        enforceNotIsolatedCaller("broadcastIntent");
14117        synchronized(this) {
14118            intent = verifyBroadcastLocked(intent);
14119
14120            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14121            final int callingPid = Binder.getCallingPid();
14122            final int callingUid = Binder.getCallingUid();
14123            final long origId = Binder.clearCallingIdentity();
14124            int res = broadcastIntentLocked(callerApp,
14125                    callerApp != null ? callerApp.info.packageName : null,
14126                    intent, resolvedType, resultTo,
14127                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14128                    callingPid, callingUid, userId);
14129            Binder.restoreCallingIdentity(origId);
14130            return res;
14131        }
14132    }
14133
14134    int broadcastIntentInPackage(String packageName, int uid,
14135            Intent intent, String resolvedType, IIntentReceiver resultTo,
14136            int resultCode, String resultData, Bundle map,
14137            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14138        synchronized(this) {
14139            intent = verifyBroadcastLocked(intent);
14140
14141            final long origId = Binder.clearCallingIdentity();
14142            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14143                    resultTo, resultCode, resultData, map, requiredPermission,
14144                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14145            Binder.restoreCallingIdentity(origId);
14146            return res;
14147        }
14148    }
14149
14150    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14151        // Refuse possible leaked file descriptors
14152        if (intent != null && intent.hasFileDescriptors() == true) {
14153            throw new IllegalArgumentException("File descriptors passed in Intent");
14154        }
14155
14156        userId = handleIncomingUser(Binder.getCallingPid(),
14157                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14158
14159        synchronized(this) {
14160            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14161                    != PackageManager.PERMISSION_GRANTED) {
14162                String msg = "Permission Denial: unbroadcastIntent() from pid="
14163                        + Binder.getCallingPid()
14164                        + ", uid=" + Binder.getCallingUid()
14165                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14166                Slog.w(TAG, msg);
14167                throw new SecurityException(msg);
14168            }
14169            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14170            if (stickies != null) {
14171                ArrayList<Intent> list = stickies.get(intent.getAction());
14172                if (list != null) {
14173                    int N = list.size();
14174                    int i;
14175                    for (i=0; i<N; i++) {
14176                        if (intent.filterEquals(list.get(i))) {
14177                            list.remove(i);
14178                            break;
14179                        }
14180                    }
14181                    if (list.size() <= 0) {
14182                        stickies.remove(intent.getAction());
14183                    }
14184                }
14185                if (stickies.size() <= 0) {
14186                    mStickyBroadcasts.remove(userId);
14187                }
14188            }
14189        }
14190    }
14191
14192    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14193            String resultData, Bundle resultExtras, boolean resultAbort) {
14194        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14195        if (r == null) {
14196            Slog.w(TAG, "finishReceiver called but not found on queue");
14197            return false;
14198        }
14199
14200        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14201    }
14202
14203    void backgroundServicesFinishedLocked(int userId) {
14204        for (BroadcastQueue queue : mBroadcastQueues) {
14205            queue.backgroundServicesFinishedLocked(userId);
14206        }
14207    }
14208
14209    public void finishReceiver(IBinder who, int resultCode, String resultData,
14210            Bundle resultExtras, boolean resultAbort) {
14211        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14212
14213        // Refuse possible leaked file descriptors
14214        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14215            throw new IllegalArgumentException("File descriptors passed in Bundle");
14216        }
14217
14218        final long origId = Binder.clearCallingIdentity();
14219        try {
14220            boolean doNext = false;
14221            BroadcastRecord r;
14222
14223            synchronized(this) {
14224                r = broadcastRecordForReceiverLocked(who);
14225                if (r != null) {
14226                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14227                        resultData, resultExtras, resultAbort, true);
14228                }
14229            }
14230
14231            if (doNext) {
14232                r.queue.processNextBroadcast(false);
14233            }
14234            trimApplications();
14235        } finally {
14236            Binder.restoreCallingIdentity(origId);
14237        }
14238    }
14239
14240    // =========================================================
14241    // INSTRUMENTATION
14242    // =========================================================
14243
14244    public boolean startInstrumentation(ComponentName className,
14245            String profileFile, int flags, Bundle arguments,
14246            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14247            int userId) {
14248        enforceNotIsolatedCaller("startInstrumentation");
14249        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14250                userId, false, true, "startInstrumentation", null);
14251        // Refuse possible leaked file descriptors
14252        if (arguments != null && arguments.hasFileDescriptors()) {
14253            throw new IllegalArgumentException("File descriptors passed in Bundle");
14254        }
14255
14256        synchronized(this) {
14257            InstrumentationInfo ii = null;
14258            ApplicationInfo ai = null;
14259            try {
14260                ii = mContext.getPackageManager().getInstrumentationInfo(
14261                    className, STOCK_PM_FLAGS);
14262                ai = AppGlobals.getPackageManager().getApplicationInfo(
14263                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14264            } catch (PackageManager.NameNotFoundException e) {
14265            } catch (RemoteException e) {
14266            }
14267            if (ii == null) {
14268                reportStartInstrumentationFailure(watcher, className,
14269                        "Unable to find instrumentation info for: " + className);
14270                return false;
14271            }
14272            if (ai == null) {
14273                reportStartInstrumentationFailure(watcher, className,
14274                        "Unable to find instrumentation target package: " + ii.targetPackage);
14275                return false;
14276            }
14277
14278            int match = mContext.getPackageManager().checkSignatures(
14279                    ii.targetPackage, ii.packageName);
14280            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14281                String msg = "Permission Denial: starting instrumentation "
14282                        + className + " from pid="
14283                        + Binder.getCallingPid()
14284                        + ", uid=" + Binder.getCallingPid()
14285                        + " not allowed because package " + ii.packageName
14286                        + " does not have a signature matching the target "
14287                        + ii.targetPackage;
14288                reportStartInstrumentationFailure(watcher, className, msg);
14289                throw new SecurityException(msg);
14290            }
14291
14292            final long origId = Binder.clearCallingIdentity();
14293            // Instrumentation can kill and relaunch even persistent processes
14294            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14295                    "start instr");
14296            ProcessRecord app = addAppLocked(ai, false);
14297            app.instrumentationClass = className;
14298            app.instrumentationInfo = ai;
14299            app.instrumentationProfileFile = profileFile;
14300            app.instrumentationArguments = arguments;
14301            app.instrumentationWatcher = watcher;
14302            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14303            app.instrumentationResultClass = className;
14304            Binder.restoreCallingIdentity(origId);
14305        }
14306
14307        return true;
14308    }
14309
14310    /**
14311     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14312     * error to the logs, but if somebody is watching, send the report there too.  This enables
14313     * the "am" command to report errors with more information.
14314     *
14315     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14316     * @param cn The component name of the instrumentation.
14317     * @param report The error report.
14318     */
14319    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14320            ComponentName cn, String report) {
14321        Slog.w(TAG, report);
14322        try {
14323            if (watcher != null) {
14324                Bundle results = new Bundle();
14325                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14326                results.putString("Error", report);
14327                watcher.instrumentationStatus(cn, -1, results);
14328            }
14329        } catch (RemoteException e) {
14330            Slog.w(TAG, e);
14331        }
14332    }
14333
14334    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14335        if (app.instrumentationWatcher != null) {
14336            try {
14337                // NOTE:  IInstrumentationWatcher *must* be oneway here
14338                app.instrumentationWatcher.instrumentationFinished(
14339                    app.instrumentationClass,
14340                    resultCode,
14341                    results);
14342            } catch (RemoteException e) {
14343            }
14344        }
14345        if (app.instrumentationUiAutomationConnection != null) {
14346            try {
14347                app.instrumentationUiAutomationConnection.shutdown();
14348            } catch (RemoteException re) {
14349                /* ignore */
14350            }
14351            // Only a UiAutomation can set this flag and now that
14352            // it is finished we make sure it is reset to its default.
14353            mUserIsMonkey = false;
14354        }
14355        app.instrumentationWatcher = null;
14356        app.instrumentationUiAutomationConnection = null;
14357        app.instrumentationClass = null;
14358        app.instrumentationInfo = null;
14359        app.instrumentationProfileFile = null;
14360        app.instrumentationArguments = null;
14361
14362        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14363                "finished inst");
14364    }
14365
14366    public void finishInstrumentation(IApplicationThread target,
14367            int resultCode, Bundle results) {
14368        int userId = UserHandle.getCallingUserId();
14369        // Refuse possible leaked file descriptors
14370        if (results != null && results.hasFileDescriptors()) {
14371            throw new IllegalArgumentException("File descriptors passed in Intent");
14372        }
14373
14374        synchronized(this) {
14375            ProcessRecord app = getRecordForAppLocked(target);
14376            if (app == null) {
14377                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14378                return;
14379            }
14380            final long origId = Binder.clearCallingIdentity();
14381            finishInstrumentationLocked(app, resultCode, results);
14382            Binder.restoreCallingIdentity(origId);
14383        }
14384    }
14385
14386    // =========================================================
14387    // CONFIGURATION
14388    // =========================================================
14389
14390    public ConfigurationInfo getDeviceConfigurationInfo() {
14391        ConfigurationInfo config = new ConfigurationInfo();
14392        synchronized (this) {
14393            config.reqTouchScreen = mConfiguration.touchscreen;
14394            config.reqKeyboardType = mConfiguration.keyboard;
14395            config.reqNavigation = mConfiguration.navigation;
14396            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14397                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14398                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14399            }
14400            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14401                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14402                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14403            }
14404            config.reqGlEsVersion = GL_ES_VERSION;
14405        }
14406        return config;
14407    }
14408
14409    ActivityStack getFocusedStack() {
14410        return mStackSupervisor.getFocusedStack();
14411    }
14412
14413    public Configuration getConfiguration() {
14414        Configuration ci;
14415        synchronized(this) {
14416            ci = new Configuration(mConfiguration);
14417        }
14418        return ci;
14419    }
14420
14421    public void updatePersistentConfiguration(Configuration values) {
14422        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14423                "updateConfiguration()");
14424        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14425                "updateConfiguration()");
14426        if (values == null) {
14427            throw new NullPointerException("Configuration must not be null");
14428        }
14429
14430        synchronized(this) {
14431            final long origId = Binder.clearCallingIdentity();
14432            updateConfigurationLocked(values, null, true, false);
14433            Binder.restoreCallingIdentity(origId);
14434        }
14435    }
14436
14437    public void updateConfiguration(Configuration values) {
14438        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14439                "updateConfiguration()");
14440
14441        synchronized(this) {
14442            if (values == null && mWindowManager != null) {
14443                // sentinel: fetch the current configuration from the window manager
14444                values = mWindowManager.computeNewConfiguration();
14445            }
14446
14447            if (mWindowManager != null) {
14448                mProcessList.applyDisplaySize(mWindowManager);
14449            }
14450
14451            final long origId = Binder.clearCallingIdentity();
14452            if (values != null) {
14453                Settings.System.clearConfiguration(values);
14454            }
14455            updateConfigurationLocked(values, null, false, false);
14456            Binder.restoreCallingIdentity(origId);
14457        }
14458    }
14459
14460    /**
14461     * Do either or both things: (1) change the current configuration, and (2)
14462     * make sure the given activity is running with the (now) current
14463     * configuration.  Returns true if the activity has been left running, or
14464     * false if <var>starting</var> is being destroyed to match the new
14465     * configuration.
14466     * @param persistent TODO
14467     */
14468    boolean updateConfigurationLocked(Configuration values,
14469            ActivityRecord starting, boolean persistent, boolean initLocale) {
14470        int changes = 0;
14471
14472        if (values != null) {
14473            Configuration newConfig = new Configuration(mConfiguration);
14474            changes = newConfig.updateFrom(values);
14475            if (changes != 0) {
14476                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14477                    Slog.i(TAG, "Updating configuration to: " + values);
14478                }
14479
14480                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14481
14482                if (values.locale != null && !initLocale) {
14483                    saveLocaleLocked(values.locale,
14484                                     !values.locale.equals(mConfiguration.locale),
14485                                     values.userSetLocale);
14486                }
14487
14488                mConfigurationSeq++;
14489                if (mConfigurationSeq <= 0) {
14490                    mConfigurationSeq = 1;
14491                }
14492                newConfig.seq = mConfigurationSeq;
14493                mConfiguration = newConfig;
14494                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14495                mUsageStatsService.noteStartConfig(newConfig);
14496
14497                final Configuration configCopy = new Configuration(mConfiguration);
14498
14499                // TODO: If our config changes, should we auto dismiss any currently
14500                // showing dialogs?
14501                mShowDialogs = shouldShowDialogs(newConfig);
14502
14503                AttributeCache ac = AttributeCache.instance();
14504                if (ac != null) {
14505                    ac.updateConfiguration(configCopy);
14506                }
14507
14508                // Make sure all resources in our process are updated
14509                // right now, so that anyone who is going to retrieve
14510                // resource values after we return will be sure to get
14511                // the new ones.  This is especially important during
14512                // boot, where the first config change needs to guarantee
14513                // all resources have that config before following boot
14514                // code is executed.
14515                mSystemThread.applyConfigurationToResources(configCopy);
14516
14517                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14518                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14519                    msg.obj = new Configuration(configCopy);
14520                    mHandler.sendMessage(msg);
14521                }
14522
14523                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14524                    ProcessRecord app = mLruProcesses.get(i);
14525                    try {
14526                        if (app.thread != null) {
14527                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14528                                    + app.processName + " new config " + mConfiguration);
14529                            app.thread.scheduleConfigurationChanged(configCopy);
14530                        }
14531                    } catch (Exception e) {
14532                    }
14533                }
14534                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14535                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14536                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14537                        | Intent.FLAG_RECEIVER_FOREGROUND);
14538                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14539                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14540                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14541                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14542                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14543                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14544                    broadcastIntentLocked(null, null, intent,
14545                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14546                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14547                }
14548            }
14549        }
14550
14551        boolean kept = true;
14552        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14553        // mainStack is null during startup.
14554        if (mainStack != null) {
14555            if (changes != 0 && starting == null) {
14556                // If the configuration changed, and the caller is not already
14557                // in the process of starting an activity, then find the top
14558                // activity to check if its configuration needs to change.
14559                starting = mainStack.topRunningActivityLocked(null);
14560            }
14561
14562            if (starting != null) {
14563                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14564                // And we need to make sure at this point that all other activities
14565                // are made visible with the correct configuration.
14566                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14567            }
14568        }
14569
14570        if (values != null && mWindowManager != null) {
14571            mWindowManager.setNewConfiguration(mConfiguration);
14572        }
14573
14574        return kept;
14575    }
14576
14577    /**
14578     * Decide based on the configuration whether we should shouw the ANR,
14579     * crash, etc dialogs.  The idea is that if there is no affordnace to
14580     * press the on-screen buttons, we shouldn't show the dialog.
14581     *
14582     * A thought: SystemUI might also want to get told about this, the Power
14583     * dialog / global actions also might want different behaviors.
14584     */
14585    private static final boolean shouldShowDialogs(Configuration config) {
14586        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14587                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14588    }
14589
14590    /**
14591     * Save the locale.  You must be inside a synchronized (this) block.
14592     */
14593    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14594        if(isDiff) {
14595            SystemProperties.set("user.language", l.getLanguage());
14596            SystemProperties.set("user.region", l.getCountry());
14597        }
14598
14599        if(isPersist) {
14600            SystemProperties.set("persist.sys.language", l.getLanguage());
14601            SystemProperties.set("persist.sys.country", l.getCountry());
14602            SystemProperties.set("persist.sys.localevar", l.getVariant());
14603        }
14604    }
14605
14606    @Override
14607    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14608        ActivityRecord srec = ActivityRecord.forToken(token);
14609        return srec != null && srec.task.affinity != null &&
14610                srec.task.affinity.equals(destAffinity);
14611    }
14612
14613    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14614            Intent resultData) {
14615
14616        synchronized (this) {
14617            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14618            if (stack != null) {
14619                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14620            }
14621            return false;
14622        }
14623    }
14624
14625    public int getLaunchedFromUid(IBinder activityToken) {
14626        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14627        if (srec == null) {
14628            return -1;
14629        }
14630        return srec.launchedFromUid;
14631    }
14632
14633    public String getLaunchedFromPackage(IBinder activityToken) {
14634        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14635        if (srec == null) {
14636            return null;
14637        }
14638        return srec.launchedFromPackage;
14639    }
14640
14641    // =========================================================
14642    // LIFETIME MANAGEMENT
14643    // =========================================================
14644
14645    // Returns which broadcast queue the app is the current [or imminent] receiver
14646    // on, or 'null' if the app is not an active broadcast recipient.
14647    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14648        BroadcastRecord r = app.curReceiver;
14649        if (r != null) {
14650            return r.queue;
14651        }
14652
14653        // It's not the current receiver, but it might be starting up to become one
14654        synchronized (this) {
14655            for (BroadcastQueue queue : mBroadcastQueues) {
14656                r = queue.mPendingBroadcast;
14657                if (r != null && r.curApp == app) {
14658                    // found it; report which queue it's in
14659                    return queue;
14660                }
14661            }
14662        }
14663
14664        return null;
14665    }
14666
14667    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14668            boolean doingAll, long now) {
14669        if (mAdjSeq == app.adjSeq) {
14670            // This adjustment has already been computed.
14671            return app.curRawAdj;
14672        }
14673
14674        if (app.thread == null) {
14675            app.adjSeq = mAdjSeq;
14676            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14677            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14678            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14679        }
14680
14681        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14682        app.adjSource = null;
14683        app.adjTarget = null;
14684        app.empty = false;
14685        app.cached = false;
14686
14687        final int activitiesSize = app.activities.size();
14688
14689        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14690            // The max adjustment doesn't allow this app to be anything
14691            // below foreground, so it is not worth doing work for it.
14692            app.adjType = "fixed";
14693            app.adjSeq = mAdjSeq;
14694            app.curRawAdj = app.maxAdj;
14695            app.foregroundActivities = false;
14696            app.keeping = true;
14697            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14698            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14699            // System processes can do UI, and when they do we want to have
14700            // them trim their memory after the user leaves the UI.  To
14701            // facilitate this, here we need to determine whether or not it
14702            // is currently showing UI.
14703            app.systemNoUi = true;
14704            if (app == TOP_APP) {
14705                app.systemNoUi = false;
14706            } else if (activitiesSize > 0) {
14707                for (int j = 0; j < activitiesSize; j++) {
14708                    final ActivityRecord r = app.activities.get(j);
14709                    if (r.visible) {
14710                        app.systemNoUi = false;
14711                    }
14712                }
14713            }
14714            if (!app.systemNoUi) {
14715                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14716            }
14717            return (app.curAdj=app.maxAdj);
14718        }
14719
14720        app.keeping = false;
14721        app.systemNoUi = false;
14722
14723        // Determine the importance of the process, starting with most
14724        // important to least, and assign an appropriate OOM adjustment.
14725        int adj;
14726        int schedGroup;
14727        int procState;
14728        boolean foregroundActivities = false;
14729        boolean interesting = false;
14730        BroadcastQueue queue;
14731        if (app == TOP_APP) {
14732            // The last app on the list is the foreground app.
14733            adj = ProcessList.FOREGROUND_APP_ADJ;
14734            schedGroup = Process.THREAD_GROUP_DEFAULT;
14735            app.adjType = "top-activity";
14736            foregroundActivities = true;
14737            interesting = true;
14738            procState = ActivityManager.PROCESS_STATE_TOP;
14739        } else if (app.instrumentationClass != null) {
14740            // Don't want to kill running instrumentation.
14741            adj = ProcessList.FOREGROUND_APP_ADJ;
14742            schedGroup = Process.THREAD_GROUP_DEFAULT;
14743            app.adjType = "instrumentation";
14744            interesting = true;
14745            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14746        } else if ((queue = isReceivingBroadcast(app)) != null) {
14747            // An app that is currently receiving a broadcast also
14748            // counts as being in the foreground for OOM killer purposes.
14749            // It's placed in a sched group based on the nature of the
14750            // broadcast as reflected by which queue it's active in.
14751            adj = ProcessList.FOREGROUND_APP_ADJ;
14752            schedGroup = (queue == mFgBroadcastQueue)
14753                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14754            app.adjType = "broadcast";
14755            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14756        } else if (app.executingServices.size() > 0) {
14757            // An app that is currently executing a service callback also
14758            // counts as being in the foreground.
14759            adj = ProcessList.FOREGROUND_APP_ADJ;
14760            schedGroup = app.execServicesFg ?
14761                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14762            app.adjType = "exec-service";
14763            procState = ActivityManager.PROCESS_STATE_SERVICE;
14764            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14765        } else {
14766            // As far as we know the process is empty.  We may change our mind later.
14767            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14768            // At this point we don't actually know the adjustment.  Use the cached adj
14769            // value that the caller wants us to.
14770            adj = cachedAdj;
14771            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14772            app.cached = true;
14773            app.empty = true;
14774            app.adjType = "cch-empty";
14775        }
14776
14777        // Examine all activities if not already foreground.
14778        if (!foregroundActivities && activitiesSize > 0) {
14779            for (int j = 0; j < activitiesSize; j++) {
14780                final ActivityRecord r = app.activities.get(j);
14781                if (r.app != app) {
14782                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14783                            + app + "?!?");
14784                    continue;
14785                }
14786                if (r.visible) {
14787                    // App has a visible activity; only upgrade adjustment.
14788                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14789                        adj = ProcessList.VISIBLE_APP_ADJ;
14790                        app.adjType = "visible";
14791                    }
14792                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14793                        procState = ActivityManager.PROCESS_STATE_TOP;
14794                    }
14795                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14796                    app.cached = false;
14797                    app.empty = false;
14798                    foregroundActivities = true;
14799                    break;
14800                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14801                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14802                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14803                        app.adjType = "pausing";
14804                    }
14805                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14806                        procState = ActivityManager.PROCESS_STATE_TOP;
14807                    }
14808                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14809                    app.cached = false;
14810                    app.empty = false;
14811                    foregroundActivities = true;
14812                } else if (r.state == ActivityState.STOPPING) {
14813                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14814                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14815                        app.adjType = "stopping";
14816                    }
14817                    // For the process state, we will at this point consider the
14818                    // process to be cached.  It will be cached either as an activity
14819                    // or empty depending on whether the activity is finishing.  We do
14820                    // this so that we can treat the process as cached for purposes of
14821                    // memory trimming (determing current memory level, trim command to
14822                    // send to process) since there can be an arbitrary number of stopping
14823                    // processes and they should soon all go into the cached state.
14824                    if (!r.finishing) {
14825                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14826                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14827                        }
14828                    }
14829                    app.cached = false;
14830                    app.empty = false;
14831                    foregroundActivities = true;
14832                } else {
14833                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14834                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14835                        app.adjType = "cch-act";
14836                    }
14837                }
14838            }
14839        }
14840
14841        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14842            if (app.foregroundServices) {
14843                // The user is aware of this app, so make it visible.
14844                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14845                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14846                app.cached = false;
14847                app.adjType = "fg-service";
14848                schedGroup = Process.THREAD_GROUP_DEFAULT;
14849            } else if (app.forcingToForeground != null) {
14850                // The user is aware of this app, so make it visible.
14851                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14852                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14853                app.cached = false;
14854                app.adjType = "force-fg";
14855                app.adjSource = app.forcingToForeground;
14856                schedGroup = Process.THREAD_GROUP_DEFAULT;
14857            }
14858        }
14859
14860        if (app.foregroundServices) {
14861            interesting = true;
14862        }
14863
14864        if (app == mHeavyWeightProcess) {
14865            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14866                // We don't want to kill the current heavy-weight process.
14867                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14868                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14869                app.cached = false;
14870                app.adjType = "heavy";
14871            }
14872            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14873                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14874            }
14875        }
14876
14877        if (app == mHomeProcess) {
14878            if (adj > ProcessList.HOME_APP_ADJ) {
14879                // This process is hosting what we currently consider to be the
14880                // home app, so we don't want to let it go into the background.
14881                adj = ProcessList.HOME_APP_ADJ;
14882                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14883                app.cached = false;
14884                app.adjType = "home";
14885            }
14886            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14887                procState = ActivityManager.PROCESS_STATE_HOME;
14888            }
14889        }
14890
14891        if (app == mPreviousProcess && app.activities.size() > 0) {
14892            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14893                // This was the previous process that showed UI to the user.
14894                // We want to try to keep it around more aggressively, to give
14895                // a good experience around switching between two apps.
14896                adj = ProcessList.PREVIOUS_APP_ADJ;
14897                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14898                app.cached = false;
14899                app.adjType = "previous";
14900            }
14901            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14902                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14903            }
14904        }
14905
14906        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14907                + " reason=" + app.adjType);
14908
14909        // By default, we use the computed adjustment.  It may be changed if
14910        // there are applications dependent on our services or providers, but
14911        // this gives us a baseline and makes sure we don't get into an
14912        // infinite recursion.
14913        app.adjSeq = mAdjSeq;
14914        app.curRawAdj = adj;
14915        app.hasStartedServices = false;
14916
14917        if (mBackupTarget != null && app == mBackupTarget.app) {
14918            // If possible we want to avoid killing apps while they're being backed up
14919            if (adj > ProcessList.BACKUP_APP_ADJ) {
14920                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14921                adj = ProcessList.BACKUP_APP_ADJ;
14922                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14923                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14924                }
14925                app.adjType = "backup";
14926                app.cached = false;
14927            }
14928            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14929                procState = ActivityManager.PROCESS_STATE_BACKUP;
14930            }
14931        }
14932
14933        boolean mayBeTop = false;
14934
14935        for (int is = app.services.size()-1;
14936                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14937                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14938                        || procState > ActivityManager.PROCESS_STATE_TOP);
14939                is--) {
14940            ServiceRecord s = app.services.valueAt(is);
14941            if (s.startRequested) {
14942                app.hasStartedServices = true;
14943                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14944                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14945                }
14946                if (app.hasShownUi && app != mHomeProcess) {
14947                    // If this process has shown some UI, let it immediately
14948                    // go to the LRU list because it may be pretty heavy with
14949                    // UI stuff.  We'll tag it with a label just to help
14950                    // debug and understand what is going on.
14951                    if (adj > ProcessList.SERVICE_ADJ) {
14952                        app.adjType = "cch-started-ui-services";
14953                    }
14954                } else {
14955                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14956                        // This service has seen some activity within
14957                        // recent memory, so we will keep its process ahead
14958                        // of the background processes.
14959                        if (adj > ProcessList.SERVICE_ADJ) {
14960                            adj = ProcessList.SERVICE_ADJ;
14961                            app.adjType = "started-services";
14962                            app.cached = false;
14963                        }
14964                    }
14965                    // If we have let the service slide into the background
14966                    // state, still have some text describing what it is doing
14967                    // even though the service no longer has an impact.
14968                    if (adj > ProcessList.SERVICE_ADJ) {
14969                        app.adjType = "cch-started-services";
14970                    }
14971                }
14972                // Don't kill this process because it is doing work; it
14973                // has said it is doing work.
14974                app.keeping = true;
14975            }
14976            for (int conni = s.connections.size()-1;
14977                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14978                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14979                            || procState > ActivityManager.PROCESS_STATE_TOP);
14980                    conni--) {
14981                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14982                for (int i = 0;
14983                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14984                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14985                                || procState > ActivityManager.PROCESS_STATE_TOP);
14986                        i++) {
14987                    // XXX should compute this based on the max of
14988                    // all connected clients.
14989                    ConnectionRecord cr = clist.get(i);
14990                    if (cr.binding.client == app) {
14991                        // Binding to ourself is not interesting.
14992                        continue;
14993                    }
14994                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14995                        ProcessRecord client = cr.binding.client;
14996                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14997                                TOP_APP, doingAll, now);
14998                        int clientProcState = client.curProcState;
14999                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15000                            // If the other app is cached for any reason, for purposes here
15001                            // we are going to consider it empty.  The specific cached state
15002                            // doesn't propagate except under certain conditions.
15003                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15004                        }
15005                        String adjType = null;
15006                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15007                            // Not doing bind OOM management, so treat
15008                            // this guy more like a started service.
15009                            if (app.hasShownUi && app != mHomeProcess) {
15010                                // If this process has shown some UI, let it immediately
15011                                // go to the LRU list because it may be pretty heavy with
15012                                // UI stuff.  We'll tag it with a label just to help
15013                                // debug and understand what is going on.
15014                                if (adj > clientAdj) {
15015                                    adjType = "cch-bound-ui-services";
15016                                }
15017                                app.cached = false;
15018                                clientAdj = adj;
15019                                clientProcState = procState;
15020                            } else {
15021                                if (now >= (s.lastActivity
15022                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15023                                    // This service has not seen activity within
15024                                    // recent memory, so allow it to drop to the
15025                                    // LRU list if there is no other reason to keep
15026                                    // it around.  We'll also tag it with a label just
15027                                    // to help debug and undertand what is going on.
15028                                    if (adj > clientAdj) {
15029                                        adjType = "cch-bound-services";
15030                                    }
15031                                    clientAdj = adj;
15032                                }
15033                            }
15034                        }
15035                        if (adj > clientAdj) {
15036                            // If this process has recently shown UI, and
15037                            // the process that is binding to it is less
15038                            // important than being visible, then we don't
15039                            // care about the binding as much as we care
15040                            // about letting this process get into the LRU
15041                            // list to be killed and restarted if needed for
15042                            // memory.
15043                            if (app.hasShownUi && app != mHomeProcess
15044                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15045                                adjType = "cch-bound-ui-services";
15046                            } else {
15047                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15048                                        |Context.BIND_IMPORTANT)) != 0) {
15049                                    adj = clientAdj;
15050                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15051                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15052                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15053                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15054                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15055                                    adj = clientAdj;
15056                                } else {
15057                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15058                                        adj = ProcessList.VISIBLE_APP_ADJ;
15059                                    }
15060                                }
15061                                if (!client.cached) {
15062                                    app.cached = false;
15063                                }
15064                                if (client.keeping) {
15065                                    app.keeping = true;
15066                                }
15067                                adjType = "service";
15068                            }
15069                        }
15070                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15071                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15072                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15073                            }
15074                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15075                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15076                                    // Special handling of clients who are in the top state.
15077                                    // We *may* want to consider this process to be in the
15078                                    // top state as well, but only if there is not another
15079                                    // reason for it to be running.  Being on the top is a
15080                                    // special state, meaning you are specifically running
15081                                    // for the current top app.  If the process is already
15082                                    // running in the background for some other reason, it
15083                                    // is more important to continue considering it to be
15084                                    // in the background state.
15085                                    mayBeTop = true;
15086                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15087                                } else {
15088                                    // Special handling for above-top states (persistent
15089                                    // processes).  These should not bring the current process
15090                                    // into the top state, since they are not on top.  Instead
15091                                    // give them the best state after that.
15092                                    clientProcState =
15093                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15094                                }
15095                            }
15096                        } else {
15097                            if (clientProcState <
15098                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15099                                clientProcState =
15100                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15101                            }
15102                        }
15103                        if (procState > clientProcState) {
15104                            procState = clientProcState;
15105                        }
15106                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15107                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15108                            app.pendingUiClean = true;
15109                        }
15110                        if (adjType != null) {
15111                            app.adjType = adjType;
15112                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15113                                    .REASON_SERVICE_IN_USE;
15114                            app.adjSource = cr.binding.client;
15115                            app.adjSourceOom = clientAdj;
15116                            app.adjTarget = s.name;
15117                        }
15118                    }
15119                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15120                        app.treatLikeActivity = true;
15121                    }
15122                    final ActivityRecord a = cr.activity;
15123                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15124                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15125                                (a.visible || a.state == ActivityState.RESUMED
15126                                 || a.state == ActivityState.PAUSING)) {
15127                            adj = ProcessList.FOREGROUND_APP_ADJ;
15128                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15129                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15130                            }
15131                            app.cached = false;
15132                            app.adjType = "service";
15133                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15134                                    .REASON_SERVICE_IN_USE;
15135                            app.adjSource = a;
15136                            app.adjSourceOom = adj;
15137                            app.adjTarget = s.name;
15138                        }
15139                    }
15140                }
15141            }
15142        }
15143
15144        for (int provi = app.pubProviders.size()-1;
15145                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15146                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15147                        || procState > ActivityManager.PROCESS_STATE_TOP);
15148                provi--) {
15149            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15150            for (int i = cpr.connections.size()-1;
15151                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15152                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15153                            || procState > ActivityManager.PROCESS_STATE_TOP);
15154                    i--) {
15155                ContentProviderConnection conn = cpr.connections.get(i);
15156                ProcessRecord client = conn.client;
15157                if (client == app) {
15158                    // Being our own client is not interesting.
15159                    continue;
15160                }
15161                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15162                int clientProcState = client.curProcState;
15163                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15164                    // If the other app is cached for any reason, for purposes here
15165                    // we are going to consider it empty.
15166                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15167                }
15168                if (adj > clientAdj) {
15169                    if (app.hasShownUi && app != mHomeProcess
15170                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15171                        app.adjType = "cch-ui-provider";
15172                    } else {
15173                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15174                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15175                        app.adjType = "provider";
15176                    }
15177                    app.cached &= client.cached;
15178                    app.keeping |= client.keeping;
15179                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15180                            .REASON_PROVIDER_IN_USE;
15181                    app.adjSource = client;
15182                    app.adjSourceOom = clientAdj;
15183                    app.adjTarget = cpr.name;
15184                }
15185                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15186                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15187                        // Special handling of clients who are in the top state.
15188                        // We *may* want to consider this process to be in the
15189                        // top state as well, but only if there is not another
15190                        // reason for it to be running.  Being on the top is a
15191                        // special state, meaning you are specifically running
15192                        // for the current top app.  If the process is already
15193                        // running in the background for some other reason, it
15194                        // is more important to continue considering it to be
15195                        // in the background state.
15196                        mayBeTop = true;
15197                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15198                    } else {
15199                        // Special handling for above-top states (persistent
15200                        // processes).  These should not bring the current process
15201                        // into the top state, since they are not on top.  Instead
15202                        // give them the best state after that.
15203                        clientProcState =
15204                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15205                    }
15206                }
15207                if (procState > clientProcState) {
15208                    procState = clientProcState;
15209                }
15210                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15211                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15212                }
15213            }
15214            // If the provider has external (non-framework) process
15215            // dependencies, ensure that its adjustment is at least
15216            // FOREGROUND_APP_ADJ.
15217            if (cpr.hasExternalProcessHandles()) {
15218                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15219                    adj = ProcessList.FOREGROUND_APP_ADJ;
15220                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15221                    app.cached = false;
15222                    app.keeping = true;
15223                    app.adjType = "provider";
15224                    app.adjTarget = cpr.name;
15225                }
15226                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15227                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15228                }
15229            }
15230        }
15231
15232        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15233            // A client of one of our services or providers is in the top state.  We
15234            // *may* want to be in the top state, but not if we are already running in
15235            // the background for some other reason.  For the decision here, we are going
15236            // to pick out a few specific states that we want to remain in when a client
15237            // is top (states that tend to be longer-term) and otherwise allow it to go
15238            // to the top state.
15239            switch (procState) {
15240                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15241                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15242                case ActivityManager.PROCESS_STATE_SERVICE:
15243                    // These all are longer-term states, so pull them up to the top
15244                    // of the background states, but not all the way to the top state.
15245                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15246                    break;
15247                default:
15248                    // Otherwise, top is a better choice, so take it.
15249                    procState = ActivityManager.PROCESS_STATE_TOP;
15250                    break;
15251            }
15252        }
15253
15254        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15255            if (app.hasClientActivities) {
15256                // This is a cached process, but with client activities.  Mark it so.
15257                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15258                app.adjType = "cch-client-act";
15259            } else if (app.treatLikeActivity) {
15260                // This is a cached process, but somebody wants us to treat it like it has
15261                // an activity, okay!
15262                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15263                app.adjType = "cch-as-act";
15264            }
15265        }
15266
15267        if (adj == ProcessList.SERVICE_ADJ) {
15268            if (doingAll) {
15269                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15270                mNewNumServiceProcs++;
15271                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15272                if (!app.serviceb) {
15273                    // This service isn't far enough down on the LRU list to
15274                    // normally be a B service, but if we are low on RAM and it
15275                    // is large we want to force it down since we would prefer to
15276                    // keep launcher over it.
15277                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15278                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15279                        app.serviceHighRam = true;
15280                        app.serviceb = true;
15281                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15282                    } else {
15283                        mNewNumAServiceProcs++;
15284                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15285                    }
15286                } else {
15287                    app.serviceHighRam = false;
15288                }
15289            }
15290            if (app.serviceb) {
15291                adj = ProcessList.SERVICE_B_ADJ;
15292            }
15293        }
15294
15295        app.curRawAdj = adj;
15296
15297        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15298        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15299        if (adj > app.maxAdj) {
15300            adj = app.maxAdj;
15301            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15302                schedGroup = Process.THREAD_GROUP_DEFAULT;
15303            }
15304        }
15305        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15306            app.keeping = true;
15307        }
15308
15309        // Do final modification to adj.  Everything we do between here and applying
15310        // the final setAdj must be done in this function, because we will also use
15311        // it when computing the final cached adj later.  Note that we don't need to
15312        // worry about this for max adj above, since max adj will always be used to
15313        // keep it out of the cached vaues.
15314        app.curAdj = app.modifyRawOomAdj(adj);
15315        app.curSchedGroup = schedGroup;
15316        app.curProcState = procState;
15317        app.foregroundActivities = foregroundActivities;
15318
15319        return app.curRawAdj;
15320    }
15321
15322    /**
15323     * Schedule PSS collection of a process.
15324     */
15325    void requestPssLocked(ProcessRecord proc, int procState) {
15326        if (mPendingPssProcesses.contains(proc)) {
15327            return;
15328        }
15329        if (mPendingPssProcesses.size() == 0) {
15330            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15331        }
15332        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15333        proc.pssProcState = procState;
15334        mPendingPssProcesses.add(proc);
15335    }
15336
15337    /**
15338     * Schedule PSS collection of all processes.
15339     */
15340    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15341        if (!always) {
15342            if (now < (mLastFullPssTime +
15343                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15344                return;
15345            }
15346        }
15347        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15348        mLastFullPssTime = now;
15349        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15350        mPendingPssProcesses.clear();
15351        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15352            ProcessRecord app = mLruProcesses.get(i);
15353            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15354                app.pssProcState = app.setProcState;
15355                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15356                        isSleeping(), now);
15357                mPendingPssProcesses.add(app);
15358            }
15359        }
15360        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15361    }
15362
15363    /**
15364     * Ask a given process to GC right now.
15365     */
15366    final void performAppGcLocked(ProcessRecord app) {
15367        try {
15368            app.lastRequestedGc = SystemClock.uptimeMillis();
15369            if (app.thread != null) {
15370                if (app.reportLowMemory) {
15371                    app.reportLowMemory = false;
15372                    app.thread.scheduleLowMemory();
15373                } else {
15374                    app.thread.processInBackground();
15375                }
15376            }
15377        } catch (Exception e) {
15378            // whatever.
15379        }
15380    }
15381
15382    /**
15383     * Returns true if things are idle enough to perform GCs.
15384     */
15385    private final boolean canGcNowLocked() {
15386        boolean processingBroadcasts = false;
15387        for (BroadcastQueue q : mBroadcastQueues) {
15388            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15389                processingBroadcasts = true;
15390            }
15391        }
15392        return !processingBroadcasts
15393                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15394    }
15395
15396    /**
15397     * Perform GCs on all processes that are waiting for it, but only
15398     * if things are idle.
15399     */
15400    final void performAppGcsLocked() {
15401        final int N = mProcessesToGc.size();
15402        if (N <= 0) {
15403            return;
15404        }
15405        if (canGcNowLocked()) {
15406            while (mProcessesToGc.size() > 0) {
15407                ProcessRecord proc = mProcessesToGc.remove(0);
15408                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15409                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15410                            <= SystemClock.uptimeMillis()) {
15411                        // To avoid spamming the system, we will GC processes one
15412                        // at a time, waiting a few seconds between each.
15413                        performAppGcLocked(proc);
15414                        scheduleAppGcsLocked();
15415                        return;
15416                    } else {
15417                        // It hasn't been long enough since we last GCed this
15418                        // process...  put it in the list to wait for its time.
15419                        addProcessToGcListLocked(proc);
15420                        break;
15421                    }
15422                }
15423            }
15424
15425            scheduleAppGcsLocked();
15426        }
15427    }
15428
15429    /**
15430     * If all looks good, perform GCs on all processes waiting for them.
15431     */
15432    final void performAppGcsIfAppropriateLocked() {
15433        if (canGcNowLocked()) {
15434            performAppGcsLocked();
15435            return;
15436        }
15437        // Still not idle, wait some more.
15438        scheduleAppGcsLocked();
15439    }
15440
15441    /**
15442     * Schedule the execution of all pending app GCs.
15443     */
15444    final void scheduleAppGcsLocked() {
15445        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15446
15447        if (mProcessesToGc.size() > 0) {
15448            // Schedule a GC for the time to the next process.
15449            ProcessRecord proc = mProcessesToGc.get(0);
15450            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15451
15452            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15453            long now = SystemClock.uptimeMillis();
15454            if (when < (now+GC_TIMEOUT)) {
15455                when = now + GC_TIMEOUT;
15456            }
15457            mHandler.sendMessageAtTime(msg, when);
15458        }
15459    }
15460
15461    /**
15462     * Add a process to the array of processes waiting to be GCed.  Keeps the
15463     * list in sorted order by the last GC time.  The process can't already be
15464     * on the list.
15465     */
15466    final void addProcessToGcListLocked(ProcessRecord proc) {
15467        boolean added = false;
15468        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15469            if (mProcessesToGc.get(i).lastRequestedGc <
15470                    proc.lastRequestedGc) {
15471                added = true;
15472                mProcessesToGc.add(i+1, proc);
15473                break;
15474            }
15475        }
15476        if (!added) {
15477            mProcessesToGc.add(0, proc);
15478        }
15479    }
15480
15481    /**
15482     * Set up to ask a process to GC itself.  This will either do it
15483     * immediately, or put it on the list of processes to gc the next
15484     * time things are idle.
15485     */
15486    final void scheduleAppGcLocked(ProcessRecord app) {
15487        long now = SystemClock.uptimeMillis();
15488        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15489            return;
15490        }
15491        if (!mProcessesToGc.contains(app)) {
15492            addProcessToGcListLocked(app);
15493            scheduleAppGcsLocked();
15494        }
15495    }
15496
15497    final void checkExcessivePowerUsageLocked(boolean doKills) {
15498        updateCpuStatsNow();
15499
15500        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15501        boolean doWakeKills = doKills;
15502        boolean doCpuKills = doKills;
15503        if (mLastPowerCheckRealtime == 0) {
15504            doWakeKills = false;
15505        }
15506        if (mLastPowerCheckUptime == 0) {
15507            doCpuKills = false;
15508        }
15509        if (stats.isScreenOn()) {
15510            doWakeKills = false;
15511        }
15512        final long curRealtime = SystemClock.elapsedRealtime();
15513        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15514        final long curUptime = SystemClock.uptimeMillis();
15515        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15516        mLastPowerCheckRealtime = curRealtime;
15517        mLastPowerCheckUptime = curUptime;
15518        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15519            doWakeKills = false;
15520        }
15521        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15522            doCpuKills = false;
15523        }
15524        int i = mLruProcesses.size();
15525        while (i > 0) {
15526            i--;
15527            ProcessRecord app = mLruProcesses.get(i);
15528            if (!app.keeping) {
15529                long wtime;
15530                synchronized (stats) {
15531                    wtime = stats.getProcessWakeTime(app.info.uid,
15532                            app.pid, curRealtime);
15533                }
15534                long wtimeUsed = wtime - app.lastWakeTime;
15535                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15536                if (DEBUG_POWER) {
15537                    StringBuilder sb = new StringBuilder(128);
15538                    sb.append("Wake for ");
15539                    app.toShortString(sb);
15540                    sb.append(": over ");
15541                    TimeUtils.formatDuration(realtimeSince, sb);
15542                    sb.append(" used ");
15543                    TimeUtils.formatDuration(wtimeUsed, sb);
15544                    sb.append(" (");
15545                    sb.append((wtimeUsed*100)/realtimeSince);
15546                    sb.append("%)");
15547                    Slog.i(TAG, sb.toString());
15548                    sb.setLength(0);
15549                    sb.append("CPU for ");
15550                    app.toShortString(sb);
15551                    sb.append(": over ");
15552                    TimeUtils.formatDuration(uptimeSince, sb);
15553                    sb.append(" used ");
15554                    TimeUtils.formatDuration(cputimeUsed, sb);
15555                    sb.append(" (");
15556                    sb.append((cputimeUsed*100)/uptimeSince);
15557                    sb.append("%)");
15558                    Slog.i(TAG, sb.toString());
15559                }
15560                // If a process has held a wake lock for more
15561                // than 50% of the time during this period,
15562                // that sounds bad.  Kill!
15563                if (doWakeKills && realtimeSince > 0
15564                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15565                    synchronized (stats) {
15566                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15567                                realtimeSince, wtimeUsed);
15568                    }
15569                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15570                            + " during " + realtimeSince);
15571                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15572                } else if (doCpuKills && uptimeSince > 0
15573                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15574                    synchronized (stats) {
15575                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15576                                uptimeSince, cputimeUsed);
15577                    }
15578                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15579                            + " during " + uptimeSince);
15580                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15581                } else {
15582                    app.lastWakeTime = wtime;
15583                    app.lastCpuTime = app.curCpuTime;
15584                }
15585            }
15586        }
15587    }
15588
15589    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15590            ProcessRecord TOP_APP, boolean doingAll, long now) {
15591        boolean success = true;
15592
15593        if (app.curRawAdj != app.setRawAdj) {
15594            if (wasKeeping && !app.keeping) {
15595                // This app is no longer something we want to keep.  Note
15596                // its current wake lock time to later know to kill it if
15597                // it is not behaving well.
15598                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15599                synchronized (stats) {
15600                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15601                            app.pid, SystemClock.elapsedRealtime());
15602                }
15603                app.lastCpuTime = app.curCpuTime;
15604            }
15605
15606            app.setRawAdj = app.curRawAdj;
15607        }
15608
15609        int changes = 0;
15610
15611        if (app.curAdj != app.setAdj) {
15612            ProcessList.setOomAdj(app.pid, app.curAdj);
15613            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15614                TAG, "Set " + app.pid + " " + app.processName +
15615                " adj " + app.curAdj + ": " + app.adjType);
15616            app.setAdj = app.curAdj;
15617        }
15618
15619        if (app.setSchedGroup != app.curSchedGroup) {
15620            app.setSchedGroup = app.curSchedGroup;
15621            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15622                    "Setting process group of " + app.processName
15623                    + " to " + app.curSchedGroup);
15624            if (app.waitingToKill != null &&
15625                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15626                killUnneededProcessLocked(app, app.waitingToKill);
15627                success = false;
15628            } else {
15629                if (true) {
15630                    long oldId = Binder.clearCallingIdentity();
15631                    try {
15632                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15633                    } catch (Exception e) {
15634                        Slog.w(TAG, "Failed setting process group of " + app.pid
15635                                + " to " + app.curSchedGroup);
15636                        e.printStackTrace();
15637                    } finally {
15638                        Binder.restoreCallingIdentity(oldId);
15639                    }
15640                } else {
15641                    if (app.thread != null) {
15642                        try {
15643                            app.thread.setSchedulingGroup(app.curSchedGroup);
15644                        } catch (RemoteException e) {
15645                        }
15646                    }
15647                }
15648                Process.setSwappiness(app.pid,
15649                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15650            }
15651        }
15652        if (app.repForegroundActivities != app.foregroundActivities) {
15653            app.repForegroundActivities = app.foregroundActivities;
15654            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15655        }
15656        if (app.repProcState != app.curProcState) {
15657            app.repProcState = app.curProcState;
15658            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15659            if (app.thread != null) {
15660                try {
15661                    if (false) {
15662                        //RuntimeException h = new RuntimeException("here");
15663                        Slog.i(TAG, "Sending new process state " + app.repProcState
15664                                + " to " + app /*, h*/);
15665                    }
15666                    app.thread.setProcessState(app.repProcState);
15667                } catch (RemoteException e) {
15668                }
15669            }
15670        }
15671        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15672                app.setProcState)) {
15673            app.lastStateTime = now;
15674            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15675                    isSleeping(), now);
15676            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15677                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15678                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15679                    + (app.nextPssTime-now) + ": " + app);
15680        } else {
15681            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15682                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15683                requestPssLocked(app, app.setProcState);
15684                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15685                        isSleeping(), now);
15686            } else if (false && DEBUG_PSS) {
15687                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15688            }
15689        }
15690        if (app.setProcState != app.curProcState) {
15691            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15692                    "Proc state change of " + app.processName
15693                    + " to " + app.curProcState);
15694            app.setProcState = app.curProcState;
15695            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15696                app.notCachedSinceIdle = false;
15697            }
15698            if (!doingAll) {
15699                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15700            } else {
15701                app.procStateChanged = true;
15702            }
15703        }
15704
15705        if (changes != 0) {
15706            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15707            int i = mPendingProcessChanges.size()-1;
15708            ProcessChangeItem item = null;
15709            while (i >= 0) {
15710                item = mPendingProcessChanges.get(i);
15711                if (item.pid == app.pid) {
15712                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15713                    break;
15714                }
15715                i--;
15716            }
15717            if (i < 0) {
15718                // No existing item in pending changes; need a new one.
15719                final int NA = mAvailProcessChanges.size();
15720                if (NA > 0) {
15721                    item = mAvailProcessChanges.remove(NA-1);
15722                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15723                } else {
15724                    item = new ProcessChangeItem();
15725                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15726                }
15727                item.changes = 0;
15728                item.pid = app.pid;
15729                item.uid = app.info.uid;
15730                if (mPendingProcessChanges.size() == 0) {
15731                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15732                            "*** Enqueueing dispatch processes changed!");
15733                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15734                }
15735                mPendingProcessChanges.add(item);
15736            }
15737            item.changes |= changes;
15738            item.processState = app.repProcState;
15739            item.foregroundActivities = app.repForegroundActivities;
15740            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15741                    + Integer.toHexString(System.identityHashCode(item))
15742                    + " " + app.toShortString() + ": changes=" + item.changes
15743                    + " procState=" + item.processState
15744                    + " foreground=" + item.foregroundActivities
15745                    + " type=" + app.adjType + " source=" + app.adjSource
15746                    + " target=" + app.adjTarget);
15747        }
15748
15749        return success;
15750    }
15751
15752    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15753        if (proc.thread != null && proc.baseProcessTracker != null) {
15754            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15755        }
15756    }
15757
15758    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15759            ProcessRecord TOP_APP, boolean doingAll, long now) {
15760        if (app.thread == null) {
15761            return false;
15762        }
15763
15764        final boolean wasKeeping = app.keeping;
15765
15766        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15767
15768        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15769    }
15770
15771    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15772            boolean oomAdj) {
15773        if (isForeground != proc.foregroundServices) {
15774            proc.foregroundServices = isForeground;
15775            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15776                    proc.info.uid);
15777            if (isForeground) {
15778                if (curProcs == null) {
15779                    curProcs = new ArrayList<ProcessRecord>();
15780                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15781                }
15782                if (!curProcs.contains(proc)) {
15783                    curProcs.add(proc);
15784                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15785                            proc.info.packageName, proc.info.uid);
15786                }
15787            } else {
15788                if (curProcs != null) {
15789                    if (curProcs.remove(proc)) {
15790                        mBatteryStatsService.noteEvent(
15791                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15792                                proc.info.packageName, proc.info.uid);
15793                        if (curProcs.size() <= 0) {
15794                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15795                        }
15796                    }
15797                }
15798            }
15799            if (oomAdj) {
15800                updateOomAdjLocked();
15801            }
15802        }
15803    }
15804
15805    private final ActivityRecord resumedAppLocked() {
15806        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15807        String pkg;
15808        int uid;
15809        if (act != null && !act.sleeping) {
15810            pkg = act.packageName;
15811            uid = act.info.applicationInfo.uid;
15812        } else {
15813            pkg = null;
15814            uid = -1;
15815        }
15816        // Has the UID or resumed package name changed?
15817        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15818                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15819            if (mCurResumedPackage != null) {
15820                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15821                        mCurResumedPackage, mCurResumedUid);
15822            }
15823            mCurResumedPackage = pkg;
15824            mCurResumedUid = uid;
15825            if (mCurResumedPackage != null) {
15826                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15827                        mCurResumedPackage, mCurResumedUid);
15828            }
15829        }
15830        return act;
15831    }
15832
15833    final boolean updateOomAdjLocked(ProcessRecord app) {
15834        final ActivityRecord TOP_ACT = resumedAppLocked();
15835        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15836        final boolean wasCached = app.cached;
15837
15838        mAdjSeq++;
15839
15840        // This is the desired cached adjusment we want to tell it to use.
15841        // If our app is currently cached, we know it, and that is it.  Otherwise,
15842        // we don't know it yet, and it needs to now be cached we will then
15843        // need to do a complete oom adj.
15844        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15845                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15846        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15847                SystemClock.uptimeMillis());
15848        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15849            // Changed to/from cached state, so apps after it in the LRU
15850            // list may also be changed.
15851            updateOomAdjLocked();
15852        }
15853        return success;
15854    }
15855
15856    final void updateOomAdjLocked() {
15857        final ActivityRecord TOP_ACT = resumedAppLocked();
15858        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15859        final long now = SystemClock.uptimeMillis();
15860        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15861        final int N = mLruProcesses.size();
15862
15863        if (false) {
15864            RuntimeException e = new RuntimeException();
15865            e.fillInStackTrace();
15866            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15867        }
15868
15869        mAdjSeq++;
15870        mNewNumServiceProcs = 0;
15871        mNewNumAServiceProcs = 0;
15872
15873        final int emptyProcessLimit;
15874        final int cachedProcessLimit;
15875        if (mProcessLimit <= 0) {
15876            emptyProcessLimit = cachedProcessLimit = 0;
15877        } else if (mProcessLimit == 1) {
15878            emptyProcessLimit = 1;
15879            cachedProcessLimit = 0;
15880        } else {
15881            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15882            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15883        }
15884
15885        // Let's determine how many processes we have running vs.
15886        // how many slots we have for background processes; we may want
15887        // to put multiple processes in a slot of there are enough of
15888        // them.
15889        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15890                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15891        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15892        if (numEmptyProcs > cachedProcessLimit) {
15893            // If there are more empty processes than our limit on cached
15894            // processes, then use the cached process limit for the factor.
15895            // This ensures that the really old empty processes get pushed
15896            // down to the bottom, so if we are running low on memory we will
15897            // have a better chance at keeping around more cached processes
15898            // instead of a gazillion empty processes.
15899            numEmptyProcs = cachedProcessLimit;
15900        }
15901        int emptyFactor = numEmptyProcs/numSlots;
15902        if (emptyFactor < 1) emptyFactor = 1;
15903        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15904        if (cachedFactor < 1) cachedFactor = 1;
15905        int stepCached = 0;
15906        int stepEmpty = 0;
15907        int numCached = 0;
15908        int numEmpty = 0;
15909        int numTrimming = 0;
15910
15911        mNumNonCachedProcs = 0;
15912        mNumCachedHiddenProcs = 0;
15913
15914        // First update the OOM adjustment for each of the
15915        // application processes based on their current state.
15916        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15917        int nextCachedAdj = curCachedAdj+1;
15918        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15919        int nextEmptyAdj = curEmptyAdj+2;
15920        for (int i=N-1; i>=0; i--) {
15921            ProcessRecord app = mLruProcesses.get(i);
15922            if (!app.killedByAm && app.thread != null) {
15923                app.procStateChanged = false;
15924                final boolean wasKeeping = app.keeping;
15925                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15926
15927                // If we haven't yet assigned the final cached adj
15928                // to the process, do that now.
15929                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15930                    switch (app.curProcState) {
15931                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15932                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15933                            // This process is a cached process holding activities...
15934                            // assign it the next cached value for that type, and then
15935                            // step that cached level.
15936                            app.curRawAdj = curCachedAdj;
15937                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15938                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15939                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15940                                    + ")");
15941                            if (curCachedAdj != nextCachedAdj) {
15942                                stepCached++;
15943                                if (stepCached >= cachedFactor) {
15944                                    stepCached = 0;
15945                                    curCachedAdj = nextCachedAdj;
15946                                    nextCachedAdj += 2;
15947                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15948                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15949                                    }
15950                                }
15951                            }
15952                            break;
15953                        default:
15954                            // For everything else, assign next empty cached process
15955                            // level and bump that up.  Note that this means that
15956                            // long-running services that have dropped down to the
15957                            // cached level will be treated as empty (since their process
15958                            // state is still as a service), which is what we want.
15959                            app.curRawAdj = curEmptyAdj;
15960                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15961                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15962                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15963                                    + ")");
15964                            if (curEmptyAdj != nextEmptyAdj) {
15965                                stepEmpty++;
15966                                if (stepEmpty >= emptyFactor) {
15967                                    stepEmpty = 0;
15968                                    curEmptyAdj = nextEmptyAdj;
15969                                    nextEmptyAdj += 2;
15970                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15971                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15972                                    }
15973                                }
15974                            }
15975                            break;
15976                    }
15977                }
15978
15979                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15980
15981                // Count the number of process types.
15982                switch (app.curProcState) {
15983                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15984                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15985                        mNumCachedHiddenProcs++;
15986                        numCached++;
15987                        if (numCached > cachedProcessLimit) {
15988                            killUnneededProcessLocked(app, "cached #" + numCached);
15989                        }
15990                        break;
15991                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15992                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15993                                && app.lastActivityTime < oldTime) {
15994                            killUnneededProcessLocked(app, "empty for "
15995                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15996                                    / 1000) + "s");
15997                        } else {
15998                            numEmpty++;
15999                            if (numEmpty > emptyProcessLimit) {
16000                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16001                            }
16002                        }
16003                        break;
16004                    default:
16005                        mNumNonCachedProcs++;
16006                        break;
16007                }
16008
16009                if (app.isolated && app.services.size() <= 0) {
16010                    // If this is an isolated process, and there are no
16011                    // services running in it, then the process is no longer
16012                    // needed.  We agressively kill these because we can by
16013                    // definition not re-use the same process again, and it is
16014                    // good to avoid having whatever code was running in them
16015                    // left sitting around after no longer needed.
16016                    killUnneededProcessLocked(app, "isolated not needed");
16017                }
16018
16019                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16020                        && !app.killedByAm) {
16021                    numTrimming++;
16022                }
16023            }
16024        }
16025
16026        mNumServiceProcs = mNewNumServiceProcs;
16027
16028        // Now determine the memory trimming level of background processes.
16029        // Unfortunately we need to start at the back of the list to do this
16030        // properly.  We only do this if the number of background apps we
16031        // are managing to keep around is less than half the maximum we desire;
16032        // if we are keeping a good number around, we'll let them use whatever
16033        // memory they want.
16034        final int numCachedAndEmpty = numCached + numEmpty;
16035        int memFactor;
16036        if (numCached <= ProcessList.TRIM_CACHED_APPS
16037                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16038            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16039                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16040            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16041                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16042            } else {
16043                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16044            }
16045        } else {
16046            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16047        }
16048        // We always allow the memory level to go up (better).  We only allow it to go
16049        // down if we are in a state where that is allowed, *and* the total number of processes
16050        // has gone down since last time.
16051        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16052                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16053                + " last=" + mLastNumProcesses);
16054        if (memFactor > mLastMemoryLevel) {
16055            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16056                memFactor = mLastMemoryLevel;
16057                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16058            }
16059        }
16060        mLastMemoryLevel = memFactor;
16061        mLastNumProcesses = mLruProcesses.size();
16062        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16063        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16064        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16065            if (mLowRamStartTime == 0) {
16066                mLowRamStartTime = now;
16067            }
16068            int step = 0;
16069            int fgTrimLevel;
16070            switch (memFactor) {
16071                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16072                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16073                    break;
16074                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16075                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16076                    break;
16077                default:
16078                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16079                    break;
16080            }
16081            int factor = numTrimming/3;
16082            int minFactor = 2;
16083            if (mHomeProcess != null) minFactor++;
16084            if (mPreviousProcess != null) minFactor++;
16085            if (factor < minFactor) factor = minFactor;
16086            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16087            for (int i=N-1; i>=0; i--) {
16088                ProcessRecord app = mLruProcesses.get(i);
16089                if (allChanged || app.procStateChanged) {
16090                    setProcessTrackerState(app, trackerMemFactor, now);
16091                    app.procStateChanged = false;
16092                }
16093                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16094                        && !app.killedByAm) {
16095                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16096                        try {
16097                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16098                                    "Trimming memory of " + app.processName
16099                                    + " to " + curLevel);
16100                            app.thread.scheduleTrimMemory(curLevel);
16101                        } catch (RemoteException e) {
16102                        }
16103                        if (false) {
16104                            // For now we won't do this; our memory trimming seems
16105                            // to be good enough at this point that destroying
16106                            // activities causes more harm than good.
16107                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16108                                    && app != mHomeProcess && app != mPreviousProcess) {
16109                                // Need to do this on its own message because the stack may not
16110                                // be in a consistent state at this point.
16111                                // For these apps we will also finish their activities
16112                                // to help them free memory.
16113                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16114                            }
16115                        }
16116                    }
16117                    app.trimMemoryLevel = curLevel;
16118                    step++;
16119                    if (step >= factor) {
16120                        step = 0;
16121                        switch (curLevel) {
16122                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16123                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16124                                break;
16125                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16126                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16127                                break;
16128                        }
16129                    }
16130                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16131                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16132                            && app.thread != null) {
16133                        try {
16134                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16135                                    "Trimming memory of heavy-weight " + app.processName
16136                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16137                            app.thread.scheduleTrimMemory(
16138                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16139                        } catch (RemoteException e) {
16140                        }
16141                    }
16142                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16143                } else {
16144                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16145                            || app.systemNoUi) && app.pendingUiClean) {
16146                        // If this application is now in the background and it
16147                        // had done UI, then give it the special trim level to
16148                        // have it free UI resources.
16149                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16150                        if (app.trimMemoryLevel < level && app.thread != null) {
16151                            try {
16152                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16153                                        "Trimming memory of bg-ui " + app.processName
16154                                        + " to " + level);
16155                                app.thread.scheduleTrimMemory(level);
16156                            } catch (RemoteException e) {
16157                            }
16158                        }
16159                        app.pendingUiClean = false;
16160                    }
16161                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16162                        try {
16163                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16164                                    "Trimming memory of fg " + app.processName
16165                                    + " to " + fgTrimLevel);
16166                            app.thread.scheduleTrimMemory(fgTrimLevel);
16167                        } catch (RemoteException e) {
16168                        }
16169                    }
16170                    app.trimMemoryLevel = fgTrimLevel;
16171                }
16172            }
16173        } else {
16174            if (mLowRamStartTime != 0) {
16175                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16176                mLowRamStartTime = 0;
16177            }
16178            for (int i=N-1; i>=0; i--) {
16179                ProcessRecord app = mLruProcesses.get(i);
16180                if (allChanged || app.procStateChanged) {
16181                    setProcessTrackerState(app, trackerMemFactor, now);
16182                    app.procStateChanged = false;
16183                }
16184                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16185                        || app.systemNoUi) && app.pendingUiClean) {
16186                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16187                            && app.thread != null) {
16188                        try {
16189                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16190                                    "Trimming memory of ui hidden " + app.processName
16191                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16192                            app.thread.scheduleTrimMemory(
16193                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16194                        } catch (RemoteException e) {
16195                        }
16196                    }
16197                    app.pendingUiClean = false;
16198                }
16199                app.trimMemoryLevel = 0;
16200            }
16201        }
16202
16203        if (mAlwaysFinishActivities) {
16204            // Need to do this on its own message because the stack may not
16205            // be in a consistent state at this point.
16206            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16207        }
16208
16209        if (allChanged) {
16210            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16211        }
16212
16213        if (mProcessStats.shouldWriteNowLocked(now)) {
16214            mHandler.post(new Runnable() {
16215                @Override public void run() {
16216                    synchronized (ActivityManagerService.this) {
16217                        mProcessStats.writeStateAsyncLocked();
16218                    }
16219                }
16220            });
16221        }
16222
16223        if (DEBUG_OOM_ADJ) {
16224            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16225        }
16226    }
16227
16228    final void trimApplications() {
16229        synchronized (this) {
16230            int i;
16231
16232            // First remove any unused application processes whose package
16233            // has been removed.
16234            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16235                final ProcessRecord app = mRemovedProcesses.get(i);
16236                if (app.activities.size() == 0
16237                        && app.curReceiver == null && app.services.size() == 0) {
16238                    Slog.i(
16239                        TAG, "Exiting empty application process "
16240                        + app.processName + " ("
16241                        + (app.thread != null ? app.thread.asBinder() : null)
16242                        + ")\n");
16243                    if (app.pid > 0 && app.pid != MY_PID) {
16244                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16245                                app.processName, app.setAdj, "empty");
16246                        app.killedByAm = true;
16247                        Process.killProcessQuiet(app.pid);
16248                    } else {
16249                        try {
16250                            app.thread.scheduleExit();
16251                        } catch (Exception e) {
16252                            // Ignore exceptions.
16253                        }
16254                    }
16255                    cleanUpApplicationRecordLocked(app, false, true, -1);
16256                    mRemovedProcesses.remove(i);
16257
16258                    if (app.persistent) {
16259                        if (app.persistent) {
16260                            addAppLocked(app.info, false);
16261                        }
16262                    }
16263                }
16264            }
16265
16266            // Now update the oom adj for all processes.
16267            updateOomAdjLocked();
16268        }
16269    }
16270
16271    /** This method sends the specified signal to each of the persistent apps */
16272    public void signalPersistentProcesses(int sig) throws RemoteException {
16273        if (sig != Process.SIGNAL_USR1) {
16274            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16275        }
16276
16277        synchronized (this) {
16278            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16279                    != PackageManager.PERMISSION_GRANTED) {
16280                throw new SecurityException("Requires permission "
16281                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16282            }
16283
16284            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16285                ProcessRecord r = mLruProcesses.get(i);
16286                if (r.thread != null && r.persistent) {
16287                    Process.sendSignal(r.pid, sig);
16288                }
16289            }
16290        }
16291    }
16292
16293    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16294        if (proc == null || proc == mProfileProc) {
16295            proc = mProfileProc;
16296            path = mProfileFile;
16297            profileType = mProfileType;
16298            clearProfilerLocked();
16299        }
16300        if (proc == null) {
16301            return;
16302        }
16303        try {
16304            proc.thread.profilerControl(false, path, null, profileType);
16305        } catch (RemoteException e) {
16306            throw new IllegalStateException("Process disappeared");
16307        }
16308    }
16309
16310    private void clearProfilerLocked() {
16311        if (mProfileFd != null) {
16312            try {
16313                mProfileFd.close();
16314            } catch (IOException e) {
16315            }
16316        }
16317        mProfileApp = null;
16318        mProfileProc = null;
16319        mProfileFile = null;
16320        mProfileType = 0;
16321        mAutoStopProfiler = false;
16322    }
16323
16324    public boolean profileControl(String process, int userId, boolean start,
16325            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16326
16327        try {
16328            synchronized (this) {
16329                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16330                // its own permission.
16331                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16332                        != PackageManager.PERMISSION_GRANTED) {
16333                    throw new SecurityException("Requires permission "
16334                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16335                }
16336
16337                if (start && fd == null) {
16338                    throw new IllegalArgumentException("null fd");
16339                }
16340
16341                ProcessRecord proc = null;
16342                if (process != null) {
16343                    proc = findProcessLocked(process, userId, "profileControl");
16344                }
16345
16346                if (start && (proc == null || proc.thread == null)) {
16347                    throw new IllegalArgumentException("Unknown process: " + process);
16348                }
16349
16350                if (start) {
16351                    stopProfilerLocked(null, null, 0);
16352                    setProfileApp(proc.info, proc.processName, path, fd, false);
16353                    mProfileProc = proc;
16354                    mProfileType = profileType;
16355                    try {
16356                        fd = fd.dup();
16357                    } catch (IOException e) {
16358                        fd = null;
16359                    }
16360                    proc.thread.profilerControl(start, path, fd, profileType);
16361                    fd = null;
16362                    mProfileFd = null;
16363                } else {
16364                    stopProfilerLocked(proc, path, profileType);
16365                    if (fd != null) {
16366                        try {
16367                            fd.close();
16368                        } catch (IOException e) {
16369                        }
16370                    }
16371                }
16372
16373                return true;
16374            }
16375        } catch (RemoteException e) {
16376            throw new IllegalStateException("Process disappeared");
16377        } finally {
16378            if (fd != null) {
16379                try {
16380                    fd.close();
16381                } catch (IOException e) {
16382                }
16383            }
16384        }
16385    }
16386
16387    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16388        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16389                userId, true, true, callName, null);
16390        ProcessRecord proc = null;
16391        try {
16392            int pid = Integer.parseInt(process);
16393            synchronized (mPidsSelfLocked) {
16394                proc = mPidsSelfLocked.get(pid);
16395            }
16396        } catch (NumberFormatException e) {
16397        }
16398
16399        if (proc == null) {
16400            ArrayMap<String, SparseArray<ProcessRecord>> all
16401                    = mProcessNames.getMap();
16402            SparseArray<ProcessRecord> procs = all.get(process);
16403            if (procs != null && procs.size() > 0) {
16404                proc = procs.valueAt(0);
16405                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16406                    for (int i=1; i<procs.size(); i++) {
16407                        ProcessRecord thisProc = procs.valueAt(i);
16408                        if (thisProc.userId == userId) {
16409                            proc = thisProc;
16410                            break;
16411                        }
16412                    }
16413                }
16414            }
16415        }
16416
16417        return proc;
16418    }
16419
16420    public boolean dumpHeap(String process, int userId, boolean managed,
16421            String path, ParcelFileDescriptor fd) throws RemoteException {
16422
16423        try {
16424            synchronized (this) {
16425                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16426                // its own permission (same as profileControl).
16427                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16428                        != PackageManager.PERMISSION_GRANTED) {
16429                    throw new SecurityException("Requires permission "
16430                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16431                }
16432
16433                if (fd == null) {
16434                    throw new IllegalArgumentException("null fd");
16435                }
16436
16437                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16438                if (proc == null || proc.thread == null) {
16439                    throw new IllegalArgumentException("Unknown process: " + process);
16440                }
16441
16442                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16443                if (!isDebuggable) {
16444                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16445                        throw new SecurityException("Process not debuggable: " + proc);
16446                    }
16447                }
16448
16449                proc.thread.dumpHeap(managed, path, fd);
16450                fd = null;
16451                return true;
16452            }
16453        } catch (RemoteException e) {
16454            throw new IllegalStateException("Process disappeared");
16455        } finally {
16456            if (fd != null) {
16457                try {
16458                    fd.close();
16459                } catch (IOException e) {
16460                }
16461            }
16462        }
16463    }
16464
16465    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16466    public void monitor() {
16467        synchronized (this) { }
16468    }
16469
16470    void onCoreSettingsChange(Bundle settings) {
16471        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16472            ProcessRecord processRecord = mLruProcesses.get(i);
16473            try {
16474                if (processRecord.thread != null) {
16475                    processRecord.thread.setCoreSettings(settings);
16476                }
16477            } catch (RemoteException re) {
16478                /* ignore */
16479            }
16480        }
16481    }
16482
16483    // Multi-user methods
16484
16485    /**
16486     * Start user, if its not already running, but don't bring it to foreground.
16487     */
16488    @Override
16489    public boolean startUserInBackground(final int userId) {
16490        return startUser(userId, /* foreground */ false);
16491    }
16492
16493    /**
16494     * Refreshes the list of users related to the current user when either a
16495     * user switch happens or when a new related user is started in the
16496     * background.
16497     */
16498    private void updateCurrentProfileIdsLocked() {
16499        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16500                mCurrentUserId, false /* enabledOnly */);
16501        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16502        for (int i = 0; i < currentProfileIds.length; i++) {
16503            currentProfileIds[i] = profiles.get(i).id;
16504        }
16505        mCurrentProfileIds = currentProfileIds;
16506    }
16507
16508    private Set getProfileIdsLocked(int userId) {
16509        Set userIds = new HashSet<Integer>();
16510        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16511                userId, false /* enabledOnly */);
16512        for (UserInfo user : profiles) {
16513            userIds.add(Integer.valueOf(user.id));
16514        }
16515        return userIds;
16516    }
16517
16518    @Override
16519    public boolean switchUser(final int userId) {
16520        return startUser(userId, /* foregound */ true);
16521    }
16522
16523    private boolean startUser(final int userId, boolean foreground) {
16524        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16525                != PackageManager.PERMISSION_GRANTED) {
16526            String msg = "Permission Denial: switchUser() from pid="
16527                    + Binder.getCallingPid()
16528                    + ", uid=" + Binder.getCallingUid()
16529                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16530            Slog.w(TAG, msg);
16531            throw new SecurityException(msg);
16532        }
16533
16534        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16535
16536        final long ident = Binder.clearCallingIdentity();
16537        try {
16538            synchronized (this) {
16539                final int oldUserId = mCurrentUserId;
16540                if (oldUserId == userId) {
16541                    return true;
16542                }
16543
16544                mStackSupervisor.setLockTaskModeLocked(null);
16545
16546                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16547                if (userInfo == null) {
16548                    Slog.w(TAG, "No user info for user #" + userId);
16549                    return false;
16550                }
16551
16552                if (foreground) {
16553                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16554                            R.anim.screen_user_enter);
16555                }
16556
16557                boolean needStart = false;
16558
16559                // If the user we are switching to is not currently started, then
16560                // we need to start it now.
16561                if (mStartedUsers.get(userId) == null) {
16562                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16563                    updateStartedUserArrayLocked();
16564                    needStart = true;
16565                }
16566
16567                final Integer userIdInt = Integer.valueOf(userId);
16568                mUserLru.remove(userIdInt);
16569                mUserLru.add(userIdInt);
16570
16571                if (foreground) {
16572                    mCurrentUserId = userId;
16573                    updateCurrentProfileIdsLocked();
16574                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16575                    // Once the internal notion of the active user has switched, we lock the device
16576                    // with the option to show the user switcher on the keyguard.
16577                    mWindowManager.lockNow(null);
16578                } else {
16579                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16580                    updateCurrentProfileIdsLocked();
16581                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16582                    mUserLru.remove(currentUserIdInt);
16583                    mUserLru.add(currentUserIdInt);
16584                }
16585
16586                final UserStartedState uss = mStartedUsers.get(userId);
16587
16588                // Make sure user is in the started state.  If it is currently
16589                // stopping, we need to knock that off.
16590                if (uss.mState == UserStartedState.STATE_STOPPING) {
16591                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16592                    // so we can just fairly silently bring the user back from
16593                    // the almost-dead.
16594                    uss.mState = UserStartedState.STATE_RUNNING;
16595                    updateStartedUserArrayLocked();
16596                    needStart = true;
16597                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16598                    // This means ACTION_SHUTDOWN has been sent, so we will
16599                    // need to treat this as a new boot of the user.
16600                    uss.mState = UserStartedState.STATE_BOOTING;
16601                    updateStartedUserArrayLocked();
16602                    needStart = true;
16603                }
16604
16605                if (uss.mState == UserStartedState.STATE_BOOTING) {
16606                    // Booting up a new user, need to tell system services about it.
16607                    // Note that this is on the same handler as scheduling of broadcasts,
16608                    // which is important because it needs to go first.
16609                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16610                }
16611
16612                if (foreground) {
16613                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16614                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16615                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16616                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16617                            oldUserId, userId, uss));
16618                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16619                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16620                }
16621
16622                if (needStart) {
16623                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16624                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16625                            | Intent.FLAG_RECEIVER_FOREGROUND);
16626                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16627                    broadcastIntentLocked(null, null, intent,
16628                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16629                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16630                }
16631
16632                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16633                    if (userId != UserHandle.USER_OWNER) {
16634                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16635                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16636                        broadcastIntentLocked(null, null, intent, null,
16637                                new IIntentReceiver.Stub() {
16638                                    public void performReceive(Intent intent, int resultCode,
16639                                            String data, Bundle extras, boolean ordered,
16640                                            boolean sticky, int sendingUser) {
16641                                        userInitialized(uss, userId);
16642                                    }
16643                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16644                                true, false, MY_PID, Process.SYSTEM_UID,
16645                                userId);
16646                        uss.initializing = true;
16647                    } else {
16648                        getUserManagerLocked().makeInitialized(userInfo.id);
16649                    }
16650                }
16651
16652                if (foreground) {
16653                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16654                    if (homeInFront) {
16655                        startHomeActivityLocked(userId);
16656                    } else {
16657                        mStackSupervisor.resumeTopActivitiesLocked();
16658                    }
16659                    EventLogTags.writeAmSwitchUser(userId);
16660                    getUserManagerLocked().userForeground(userId);
16661                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16662                } else {
16663                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16664                }
16665
16666                if (needStart) {
16667                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16668                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16669                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16670                    broadcastIntentLocked(null, null, intent,
16671                            null, new IIntentReceiver.Stub() {
16672                                @Override
16673                                public void performReceive(Intent intent, int resultCode, String data,
16674                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16675                                        throws RemoteException {
16676                                }
16677                            }, 0, null, null,
16678                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16679                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16680                }
16681            }
16682        } finally {
16683            Binder.restoreCallingIdentity(ident);
16684        }
16685
16686        return true;
16687    }
16688
16689    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16690        long ident = Binder.clearCallingIdentity();
16691        try {
16692            Intent intent;
16693            if (oldUserId >= 0) {
16694                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16695                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16696                        | Intent.FLAG_RECEIVER_FOREGROUND);
16697                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16698                broadcastIntentLocked(null, null, intent,
16699                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16700                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16701            }
16702            if (newUserId >= 0) {
16703                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16704                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16705                        | Intent.FLAG_RECEIVER_FOREGROUND);
16706                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16707                broadcastIntentLocked(null, null, intent,
16708                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16709                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16710                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16711                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16712                        | Intent.FLAG_RECEIVER_FOREGROUND);
16713                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16714                broadcastIntentLocked(null, null, intent,
16715                        null, null, 0, null, null,
16716                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16717                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16718            }
16719        } finally {
16720            Binder.restoreCallingIdentity(ident);
16721        }
16722    }
16723
16724    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16725            final int newUserId) {
16726        final int N = mUserSwitchObservers.beginBroadcast();
16727        if (N > 0) {
16728            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16729                int mCount = 0;
16730                @Override
16731                public void sendResult(Bundle data) throws RemoteException {
16732                    synchronized (ActivityManagerService.this) {
16733                        if (mCurUserSwitchCallback == this) {
16734                            mCount++;
16735                            if (mCount == N) {
16736                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16737                            }
16738                        }
16739                    }
16740                }
16741            };
16742            synchronized (this) {
16743                uss.switching = true;
16744                mCurUserSwitchCallback = callback;
16745            }
16746            for (int i=0; i<N; i++) {
16747                try {
16748                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16749                            newUserId, callback);
16750                } catch (RemoteException e) {
16751                }
16752            }
16753        } else {
16754            synchronized (this) {
16755                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16756            }
16757        }
16758        mUserSwitchObservers.finishBroadcast();
16759    }
16760
16761    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16762        synchronized (this) {
16763            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16764            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16765        }
16766    }
16767
16768    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16769        mCurUserSwitchCallback = null;
16770        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16771        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16772                oldUserId, newUserId, uss));
16773    }
16774
16775    void userInitialized(UserStartedState uss, int newUserId) {
16776        completeSwitchAndInitalize(uss, newUserId, true, false);
16777    }
16778
16779    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16780        completeSwitchAndInitalize(uss, newUserId, false, true);
16781    }
16782
16783    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16784            boolean clearInitializing, boolean clearSwitching) {
16785        boolean unfrozen = false;
16786        synchronized (this) {
16787            if (clearInitializing) {
16788                uss.initializing = false;
16789                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16790            }
16791            if (clearSwitching) {
16792                uss.switching = false;
16793            }
16794            if (!uss.switching && !uss.initializing) {
16795                mWindowManager.stopFreezingScreen();
16796                unfrozen = true;
16797            }
16798        }
16799        if (unfrozen) {
16800            final int N = mUserSwitchObservers.beginBroadcast();
16801            for (int i=0; i<N; i++) {
16802                try {
16803                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16804                } catch (RemoteException e) {
16805                }
16806            }
16807            mUserSwitchObservers.finishBroadcast();
16808        }
16809    }
16810
16811    void scheduleStartProfilesLocked() {
16812        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16813            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16814                    DateUtils.SECOND_IN_MILLIS);
16815        }
16816    }
16817
16818    void startProfilesLocked() {
16819        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16820        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16821                mCurrentUserId, false /* enabledOnly */);
16822        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16823        for (UserInfo user : profiles) {
16824            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16825                    && user.id != mCurrentUserId) {
16826                toStart.add(user);
16827            }
16828        }
16829        final int n = toStart.size();
16830        int i = 0;
16831        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16832            startUserInBackground(toStart.get(i).id);
16833        }
16834        if (i < n) {
16835            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16836        }
16837    }
16838
16839    void finishUserBoot(UserStartedState uss) {
16840        synchronized (this) {
16841            if (uss.mState == UserStartedState.STATE_BOOTING
16842                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16843                uss.mState = UserStartedState.STATE_RUNNING;
16844                final int userId = uss.mHandle.getIdentifier();
16845                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16846                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16847                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16848                broadcastIntentLocked(null, null, intent,
16849                        null, null, 0, null, null,
16850                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16851                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16852            }
16853        }
16854    }
16855
16856    void finishUserSwitch(UserStartedState uss) {
16857        synchronized (this) {
16858            finishUserBoot(uss);
16859
16860            startProfilesLocked();
16861
16862            int num = mUserLru.size();
16863            int i = 0;
16864            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16865                Integer oldUserId = mUserLru.get(i);
16866                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16867                if (oldUss == null) {
16868                    // Shouldn't happen, but be sane if it does.
16869                    mUserLru.remove(i);
16870                    num--;
16871                    continue;
16872                }
16873                if (oldUss.mState == UserStartedState.STATE_STOPPING
16874                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16875                    // This user is already stopping, doesn't count.
16876                    num--;
16877                    i++;
16878                    continue;
16879                }
16880                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16881                    // Owner and current can't be stopped, but count as running.
16882                    i++;
16883                    continue;
16884                }
16885                // This is a user to be stopped.
16886                stopUserLocked(oldUserId, null);
16887                num--;
16888                i++;
16889            }
16890        }
16891    }
16892
16893    @Override
16894    public int stopUser(final int userId, final IStopUserCallback callback) {
16895        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16896                != PackageManager.PERMISSION_GRANTED) {
16897            String msg = "Permission Denial: switchUser() from pid="
16898                    + Binder.getCallingPid()
16899                    + ", uid=" + Binder.getCallingUid()
16900                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16901            Slog.w(TAG, msg);
16902            throw new SecurityException(msg);
16903        }
16904        if (userId <= 0) {
16905            throw new IllegalArgumentException("Can't stop primary user " + userId);
16906        }
16907        synchronized (this) {
16908            return stopUserLocked(userId, callback);
16909        }
16910    }
16911
16912    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16913        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16914        if (mCurrentUserId == userId) {
16915            return ActivityManager.USER_OP_IS_CURRENT;
16916        }
16917
16918        final UserStartedState uss = mStartedUsers.get(userId);
16919        if (uss == null) {
16920            // User is not started, nothing to do...  but we do need to
16921            // callback if requested.
16922            if (callback != null) {
16923                mHandler.post(new Runnable() {
16924                    @Override
16925                    public void run() {
16926                        try {
16927                            callback.userStopped(userId);
16928                        } catch (RemoteException e) {
16929                        }
16930                    }
16931                });
16932            }
16933            return ActivityManager.USER_OP_SUCCESS;
16934        }
16935
16936        if (callback != null) {
16937            uss.mStopCallbacks.add(callback);
16938        }
16939
16940        if (uss.mState != UserStartedState.STATE_STOPPING
16941                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16942            uss.mState = UserStartedState.STATE_STOPPING;
16943            updateStartedUserArrayLocked();
16944
16945            long ident = Binder.clearCallingIdentity();
16946            try {
16947                // We are going to broadcast ACTION_USER_STOPPING and then
16948                // once that is done send a final ACTION_SHUTDOWN and then
16949                // stop the user.
16950                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16951                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16952                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16953                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16954                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16955                // This is the result receiver for the final shutdown broadcast.
16956                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16957                    @Override
16958                    public void performReceive(Intent intent, int resultCode, String data,
16959                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16960                        finishUserStop(uss);
16961                    }
16962                };
16963                // This is the result receiver for the initial stopping broadcast.
16964                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16965                    @Override
16966                    public void performReceive(Intent intent, int resultCode, String data,
16967                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16968                        // On to the next.
16969                        synchronized (ActivityManagerService.this) {
16970                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16971                                // Whoops, we are being started back up.  Abort, abort!
16972                                return;
16973                            }
16974                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16975                        }
16976                        mSystemServiceManager.stopUser(userId);
16977                        broadcastIntentLocked(null, null, shutdownIntent,
16978                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16979                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16980                    }
16981                };
16982                // Kick things off.
16983                broadcastIntentLocked(null, null, stoppingIntent,
16984                        null, stoppingReceiver, 0, null, null,
16985                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16986                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16987            } finally {
16988                Binder.restoreCallingIdentity(ident);
16989            }
16990        }
16991
16992        return ActivityManager.USER_OP_SUCCESS;
16993    }
16994
16995    void finishUserStop(UserStartedState uss) {
16996        final int userId = uss.mHandle.getIdentifier();
16997        boolean stopped;
16998        ArrayList<IStopUserCallback> callbacks;
16999        synchronized (this) {
17000            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17001            if (mStartedUsers.get(userId) != uss) {
17002                stopped = false;
17003            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17004                stopped = false;
17005            } else {
17006                stopped = true;
17007                // User can no longer run.
17008                mStartedUsers.remove(userId);
17009                mUserLru.remove(Integer.valueOf(userId));
17010                updateStartedUserArrayLocked();
17011
17012                // Clean up all state and processes associated with the user.
17013                // Kill all the processes for the user.
17014                forceStopUserLocked(userId, "finish user");
17015            }
17016        }
17017
17018        for (int i=0; i<callbacks.size(); i++) {
17019            try {
17020                if (stopped) callbacks.get(i).userStopped(userId);
17021                else callbacks.get(i).userStopAborted(userId);
17022            } catch (RemoteException e) {
17023            }
17024        }
17025
17026        if (stopped) {
17027            mSystemServiceManager.cleanupUser(userId);
17028            synchronized (this) {
17029                mStackSupervisor.removeUserLocked(userId);
17030            }
17031        }
17032    }
17033
17034    @Override
17035    public UserInfo getCurrentUser() {
17036        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17037                != PackageManager.PERMISSION_GRANTED) && (
17038                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17039                != PackageManager.PERMISSION_GRANTED)) {
17040            String msg = "Permission Denial: getCurrentUser() from pid="
17041                    + Binder.getCallingPid()
17042                    + ", uid=" + Binder.getCallingUid()
17043                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17044            Slog.w(TAG, msg);
17045            throw new SecurityException(msg);
17046        }
17047        synchronized (this) {
17048            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17049        }
17050    }
17051
17052    int getCurrentUserIdLocked() {
17053        return mCurrentUserId;
17054    }
17055
17056    @Override
17057    public boolean isUserRunning(int userId, boolean orStopped) {
17058        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17059                != PackageManager.PERMISSION_GRANTED) {
17060            String msg = "Permission Denial: isUserRunning() from pid="
17061                    + Binder.getCallingPid()
17062                    + ", uid=" + Binder.getCallingUid()
17063                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17064            Slog.w(TAG, msg);
17065            throw new SecurityException(msg);
17066        }
17067        synchronized (this) {
17068            return isUserRunningLocked(userId, orStopped);
17069        }
17070    }
17071
17072    boolean isUserRunningLocked(int userId, boolean orStopped) {
17073        UserStartedState state = mStartedUsers.get(userId);
17074        if (state == null) {
17075            return false;
17076        }
17077        if (orStopped) {
17078            return true;
17079        }
17080        return state.mState != UserStartedState.STATE_STOPPING
17081                && state.mState != UserStartedState.STATE_SHUTDOWN;
17082    }
17083
17084    @Override
17085    public int[] getRunningUserIds() {
17086        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17087                != PackageManager.PERMISSION_GRANTED) {
17088            String msg = "Permission Denial: isUserRunning() from pid="
17089                    + Binder.getCallingPid()
17090                    + ", uid=" + Binder.getCallingUid()
17091                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17092            Slog.w(TAG, msg);
17093            throw new SecurityException(msg);
17094        }
17095        synchronized (this) {
17096            return mStartedUserArray;
17097        }
17098    }
17099
17100    private void updateStartedUserArrayLocked() {
17101        int num = 0;
17102        for (int i=0; i<mStartedUsers.size();  i++) {
17103            UserStartedState uss = mStartedUsers.valueAt(i);
17104            // This list does not include stopping users.
17105            if (uss.mState != UserStartedState.STATE_STOPPING
17106                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17107                num++;
17108            }
17109        }
17110        mStartedUserArray = new int[num];
17111        num = 0;
17112        for (int i=0; i<mStartedUsers.size();  i++) {
17113            UserStartedState uss = mStartedUsers.valueAt(i);
17114            if (uss.mState != UserStartedState.STATE_STOPPING
17115                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17116                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17117                num++;
17118            }
17119        }
17120    }
17121
17122    @Override
17123    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17124        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17125                != PackageManager.PERMISSION_GRANTED) {
17126            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17127                    + Binder.getCallingPid()
17128                    + ", uid=" + Binder.getCallingUid()
17129                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17130            Slog.w(TAG, msg);
17131            throw new SecurityException(msg);
17132        }
17133
17134        mUserSwitchObservers.register(observer);
17135    }
17136
17137    @Override
17138    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17139        mUserSwitchObservers.unregister(observer);
17140    }
17141
17142    private boolean userExists(int userId) {
17143        if (userId == 0) {
17144            return true;
17145        }
17146        UserManagerService ums = getUserManagerLocked();
17147        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17148    }
17149
17150    int[] getUsersLocked() {
17151        UserManagerService ums = getUserManagerLocked();
17152        return ums != null ? ums.getUserIds() : new int[] { 0 };
17153    }
17154
17155    UserManagerService getUserManagerLocked() {
17156        if (mUserManager == null) {
17157            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17158            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17159        }
17160        return mUserManager;
17161    }
17162
17163    private int applyUserId(int uid, int userId) {
17164        return UserHandle.getUid(userId, uid);
17165    }
17166
17167    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17168        if (info == null) return null;
17169        ApplicationInfo newInfo = new ApplicationInfo(info);
17170        newInfo.uid = applyUserId(info.uid, userId);
17171        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17172                + info.packageName;
17173        return newInfo;
17174    }
17175
17176    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17177        if (aInfo == null
17178                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17179            return aInfo;
17180        }
17181
17182        ActivityInfo info = new ActivityInfo(aInfo);
17183        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17184        return info;
17185    }
17186
17187    private final class LocalService extends ActivityManagerInternal {
17188        @Override
17189        public void goingToSleep() {
17190            ActivityManagerService.this.goingToSleep();
17191        }
17192
17193        @Override
17194        public void wakingUp() {
17195            ActivityManagerService.this.wakingUp();
17196        }
17197    }
17198
17199    /**
17200     * An implementation of IAppTask, that allows an app to manage its own tasks via
17201     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17202     * only the process that calls getAppTasks() can call the AppTask methods.
17203     */
17204    class AppTaskImpl extends IAppTask.Stub {
17205        private int mTaskId;
17206        private int mCallingUid;
17207
17208        public AppTaskImpl(int taskId, int callingUid) {
17209            mTaskId = taskId;
17210            mCallingUid = callingUid;
17211        }
17212
17213        @Override
17214        public void finishAndRemoveTask() {
17215            // Ensure that we are called from the same process that created this AppTask
17216            if (mCallingUid != Binder.getCallingUid()) {
17217                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17218                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17219                return;
17220            }
17221
17222            synchronized (ActivityManagerService.this) {
17223                long origId = Binder.clearCallingIdentity();
17224                try {
17225                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17226                    if (tr != null) {
17227                        // Only kill the process if we are not a new document
17228                        int flags = tr.getBaseIntent().getFlags();
17229                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17230                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17231                        removeTaskByIdLocked(mTaskId,
17232                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17233                    }
17234                } finally {
17235                    Binder.restoreCallingIdentity(origId);
17236                }
17237            }
17238        }
17239
17240        @Override
17241        public ActivityManager.RecentTaskInfo getTaskInfo() {
17242            // Ensure that we are called from the same process that created this AppTask
17243            if (mCallingUid != Binder.getCallingUid()) {
17244                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17245                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17246                return null;
17247            }
17248
17249            synchronized (ActivityManagerService.this) {
17250                long origId = Binder.clearCallingIdentity();
17251                try {
17252                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17253                    if (tr != null) {
17254                        return createRecentTaskInfoFromTaskRecord(tr);
17255                    }
17256                } finally {
17257                    Binder.restoreCallingIdentity(origId);
17258                }
17259                return null;
17260            }
17261        }
17262    }
17263}
17264