ActivityManagerService.java revision f233a7b8b22ad5605c968cedd2822fa4e80c09f7
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 : 200;
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        final ComponentName comp = intent.getComponent();
3536
3537        int maxRecents = task.maxRecents - 1;
3538        for (int i=0; i<N; i++) {
3539            TaskRecord tr = mRecentTasks.get(i);
3540            if (task != tr) {
3541                if (task.userId != tr.userId) {
3542                    continue;
3543                }
3544                final Intent trIntent = tr.intent;
3545                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3546                    (intent == null || !intent.filterEquals(trIntent))) {
3547                    continue;
3548                }
3549                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3550                if (document && trIsDocument) {
3551                    // These are the same document activity (not necessarily the same doc).
3552                    if (maxRecents > 0) {
3553                        --maxRecents;
3554                        continue;
3555                    }
3556                    // Hit the maximum number of documents for this task. Fall through
3557                    // and remove this document from recents.
3558                } else if (document || trIsDocument) {
3559                    // Only one of these is a document. Not the droid we're looking for.
3560                    continue;
3561                }
3562            }
3563
3564            // Either task and tr are the same or, their affinities match or their intents match
3565            // and neither of them is a document, or they are documents using the same activity
3566            // and their maxRecents has been reached.
3567            tr.disposeThumbnail();
3568            mRecentTasks.remove(i);
3569            i--;
3570            N--;
3571            if (task.intent == null) {
3572                // If the new recent task we are adding is not fully
3573                // specified, then replace it with the existing recent task.
3574                task = tr;
3575            }
3576            mTaskPersister.notify(tr, false);
3577        }
3578        if (N >= MAX_RECENT_TASKS) {
3579            mRecentTasks.remove(N-1).disposeThumbnail();
3580        }
3581        mRecentTasks.add(0, task);
3582    }
3583
3584    @Override
3585    public void reportActivityFullyDrawn(IBinder token) {
3586        synchronized (this) {
3587            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3588            if (r == null) {
3589                return;
3590            }
3591            r.reportFullyDrawnLocked();
3592        }
3593    }
3594
3595    @Override
3596    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3597        synchronized (this) {
3598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3599            if (r == null) {
3600                return;
3601            }
3602            final long origId = Binder.clearCallingIdentity();
3603            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3604            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3605                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3606            if (config != null) {
3607                r.frozenBeforeDestroy = true;
3608                if (!updateConfigurationLocked(config, r, false, false)) {
3609                    mStackSupervisor.resumeTopActivitiesLocked();
3610                }
3611            }
3612            Binder.restoreCallingIdentity(origId);
3613        }
3614    }
3615
3616    @Override
3617    public int getRequestedOrientation(IBinder token) {
3618        synchronized (this) {
3619            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3620            if (r == null) {
3621                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3622            }
3623            return mWindowManager.getAppOrientation(r.appToken);
3624        }
3625    }
3626
3627    /**
3628     * This is the internal entry point for handling Activity.finish().
3629     *
3630     * @param token The Binder token referencing the Activity we want to finish.
3631     * @param resultCode Result code, if any, from this Activity.
3632     * @param resultData Result data (Intent), if any, from this Activity.
3633     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3634     *            the root Activity in the task.
3635     *
3636     * @return Returns true if the activity successfully finished, or false if it is still running.
3637     */
3638    @Override
3639    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3640            boolean finishTask) {
3641        // Refuse possible leaked file descriptors
3642        if (resultData != null && resultData.hasFileDescriptors() == true) {
3643            throw new IllegalArgumentException("File descriptors passed in Intent");
3644        }
3645
3646        synchronized(this) {
3647            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3648            if (r == null) {
3649                return true;
3650            }
3651            // Keep track of the root activity of the task before we finish it
3652            TaskRecord tr = r.task;
3653            ActivityRecord rootR = tr.getRootActivity();
3654            if (mController != null) {
3655                // Find the first activity that is not finishing.
3656                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3657                if (next != null) {
3658                    // ask watcher if this is allowed
3659                    boolean resumeOK = true;
3660                    try {
3661                        resumeOK = mController.activityResuming(next.packageName);
3662                    } catch (RemoteException e) {
3663                        mController = null;
3664                        Watchdog.getInstance().setActivityController(null);
3665                    }
3666
3667                    if (!resumeOK) {
3668                        return false;
3669                    }
3670                }
3671            }
3672            final long origId = Binder.clearCallingIdentity();
3673            try {
3674                boolean res;
3675                if (finishTask && r == rootR) {
3676                    // If requested, remove the task that is associated to this activity only if it
3677                    // was the root activity in the task.  The result code and data is ignored because
3678                    // we don't support returning them across task boundaries.
3679                    res = removeTaskByIdLocked(tr.taskId, 0);
3680                } else {
3681                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3682                            resultData, "app-request", true);
3683                }
3684                return res;
3685            } finally {
3686                Binder.restoreCallingIdentity(origId);
3687            }
3688        }
3689    }
3690
3691    @Override
3692    public final void finishHeavyWeightApp() {
3693        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3694                != PackageManager.PERMISSION_GRANTED) {
3695            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3696                    + Binder.getCallingPid()
3697                    + ", uid=" + Binder.getCallingUid()
3698                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3699            Slog.w(TAG, msg);
3700            throw new SecurityException(msg);
3701        }
3702
3703        synchronized(this) {
3704            if (mHeavyWeightProcess == null) {
3705                return;
3706            }
3707
3708            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3709                    mHeavyWeightProcess.activities);
3710            for (int i=0; i<activities.size(); i++) {
3711                ActivityRecord r = activities.get(i);
3712                if (!r.finishing) {
3713                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3714                            null, "finish-heavy", true);
3715                }
3716            }
3717
3718            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3719                    mHeavyWeightProcess.userId, 0));
3720            mHeavyWeightProcess = null;
3721        }
3722    }
3723
3724    @Override
3725    public void crashApplication(int uid, int initialPid, String packageName,
3726            String message) {
3727        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3728                != PackageManager.PERMISSION_GRANTED) {
3729            String msg = "Permission Denial: crashApplication() from pid="
3730                    + Binder.getCallingPid()
3731                    + ", uid=" + Binder.getCallingUid()
3732                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3733            Slog.w(TAG, msg);
3734            throw new SecurityException(msg);
3735        }
3736
3737        synchronized(this) {
3738            ProcessRecord proc = null;
3739
3740            // Figure out which process to kill.  We don't trust that initialPid
3741            // still has any relation to current pids, so must scan through the
3742            // list.
3743            synchronized (mPidsSelfLocked) {
3744                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3745                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3746                    if (p.uid != uid) {
3747                        continue;
3748                    }
3749                    if (p.pid == initialPid) {
3750                        proc = p;
3751                        break;
3752                    }
3753                    if (p.pkgList.containsKey(packageName)) {
3754                        proc = p;
3755                    }
3756                }
3757            }
3758
3759            if (proc == null) {
3760                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3761                        + " initialPid=" + initialPid
3762                        + " packageName=" + packageName);
3763                return;
3764            }
3765
3766            if (proc.thread != null) {
3767                if (proc.pid == Process.myPid()) {
3768                    Log.w(TAG, "crashApplication: trying to crash self!");
3769                    return;
3770                }
3771                long ident = Binder.clearCallingIdentity();
3772                try {
3773                    proc.thread.scheduleCrash(message);
3774                } catch (RemoteException e) {
3775                }
3776                Binder.restoreCallingIdentity(ident);
3777            }
3778        }
3779    }
3780
3781    @Override
3782    public final void finishSubActivity(IBinder token, String resultWho,
3783            int requestCode) {
3784        synchronized(this) {
3785            final long origId = Binder.clearCallingIdentity();
3786            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3787            if (r != null) {
3788                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3789            }
3790            Binder.restoreCallingIdentity(origId);
3791        }
3792    }
3793
3794    @Override
3795    public boolean finishActivityAffinity(IBinder token) {
3796        synchronized(this) {
3797            final long origId = Binder.clearCallingIdentity();
3798            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3799            boolean res = false;
3800            if (r != null) {
3801                res = r.task.stack.finishActivityAffinityLocked(r);
3802            }
3803            Binder.restoreCallingIdentity(origId);
3804            return res;
3805        }
3806    }
3807
3808    @Override
3809    public boolean willActivityBeVisible(IBinder token) {
3810        synchronized(this) {
3811            ActivityStack stack = ActivityRecord.getStackLocked(token);
3812            if (stack != null) {
3813                return stack.willActivityBeVisibleLocked(token);
3814            }
3815            return false;
3816        }
3817    }
3818
3819    @Override
3820    public void overridePendingTransition(IBinder token, String packageName,
3821            int enterAnim, int exitAnim) {
3822        synchronized(this) {
3823            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3824            if (self == null) {
3825                return;
3826            }
3827
3828            final long origId = Binder.clearCallingIdentity();
3829
3830            if (self.state == ActivityState.RESUMED
3831                    || self.state == ActivityState.PAUSING) {
3832                mWindowManager.overridePendingAppTransition(packageName,
3833                        enterAnim, exitAnim, null);
3834            }
3835
3836            Binder.restoreCallingIdentity(origId);
3837        }
3838    }
3839
3840    /**
3841     * Main function for removing an existing process from the activity manager
3842     * as a result of that process going away.  Clears out all connections
3843     * to the process.
3844     */
3845    private final void handleAppDiedLocked(ProcessRecord app,
3846            boolean restarting, boolean allowRestart) {
3847        int pid = app.pid;
3848        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3849        if (!restarting) {
3850            removeLruProcessLocked(app);
3851            if (pid > 0) {
3852                ProcessList.remove(pid);
3853            }
3854        }
3855
3856        if (mProfileProc == app) {
3857            clearProfilerLocked();
3858        }
3859
3860        // Remove this application's activities from active lists.
3861        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3862
3863        app.activities.clear();
3864
3865        if (app.instrumentationClass != null) {
3866            Slog.w(TAG, "Crash of app " + app.processName
3867                  + " running instrumentation " + app.instrumentationClass);
3868            Bundle info = new Bundle();
3869            info.putString("shortMsg", "Process crashed.");
3870            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3871        }
3872
3873        if (!restarting) {
3874            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3875                // If there was nothing to resume, and we are not already
3876                // restarting this process, but there is a visible activity that
3877                // is hosted by the process...  then make sure all visible
3878                // activities are running, taking care of restarting this
3879                // process.
3880                if (hasVisibleActivities) {
3881                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3882                }
3883            }
3884        }
3885    }
3886
3887    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3888        IBinder threadBinder = thread.asBinder();
3889        // Find the application record.
3890        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3891            ProcessRecord rec = mLruProcesses.get(i);
3892            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3893                return i;
3894            }
3895        }
3896        return -1;
3897    }
3898
3899    final ProcessRecord getRecordForAppLocked(
3900            IApplicationThread thread) {
3901        if (thread == null) {
3902            return null;
3903        }
3904
3905        int appIndex = getLRURecordIndexForAppLocked(thread);
3906        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3907    }
3908
3909    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3910        // If there are no longer any background processes running,
3911        // and the app that died was not running instrumentation,
3912        // then tell everyone we are now low on memory.
3913        boolean haveBg = false;
3914        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3915            ProcessRecord rec = mLruProcesses.get(i);
3916            if (rec.thread != null
3917                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3918                haveBg = true;
3919                break;
3920            }
3921        }
3922
3923        if (!haveBg) {
3924            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3925            if (doReport) {
3926                long now = SystemClock.uptimeMillis();
3927                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3928                    doReport = false;
3929                } else {
3930                    mLastMemUsageReportTime = now;
3931                }
3932            }
3933            final ArrayList<ProcessMemInfo> memInfos
3934                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3935            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3936            long now = SystemClock.uptimeMillis();
3937            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3938                ProcessRecord rec = mLruProcesses.get(i);
3939                if (rec == dyingProc || rec.thread == null) {
3940                    continue;
3941                }
3942                if (doReport) {
3943                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3944                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3945                }
3946                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3947                    // The low memory report is overriding any current
3948                    // state for a GC request.  Make sure to do
3949                    // heavy/important/visible/foreground processes first.
3950                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3951                        rec.lastRequestedGc = 0;
3952                    } else {
3953                        rec.lastRequestedGc = rec.lastLowMemory;
3954                    }
3955                    rec.reportLowMemory = true;
3956                    rec.lastLowMemory = now;
3957                    mProcessesToGc.remove(rec);
3958                    addProcessToGcListLocked(rec);
3959                }
3960            }
3961            if (doReport) {
3962                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3963                mHandler.sendMessage(msg);
3964            }
3965            scheduleAppGcsLocked();
3966        }
3967    }
3968
3969    final void appDiedLocked(ProcessRecord app, int pid,
3970            IApplicationThread thread) {
3971
3972        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3973        synchronized (stats) {
3974            stats.noteProcessDiedLocked(app.info.uid, pid);
3975        }
3976
3977        // Clean up already done if the process has been re-started.
3978        if (app.pid == pid && app.thread != null &&
3979                app.thread.asBinder() == thread.asBinder()) {
3980            boolean doLowMem = app.instrumentationClass == null;
3981            boolean doOomAdj = doLowMem;
3982            if (!app.killedByAm) {
3983                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3984                        + ") has died.");
3985                mAllowLowerMemLevel = true;
3986            } else {
3987                // Note that we always want to do oom adj to update our state with the
3988                // new number of procs.
3989                mAllowLowerMemLevel = false;
3990                doLowMem = false;
3991            }
3992            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3993            if (DEBUG_CLEANUP) Slog.v(
3994                TAG, "Dying app: " + app + ", pid: " + pid
3995                + ", thread: " + thread.asBinder());
3996            handleAppDiedLocked(app, false, true);
3997
3998            if (doOomAdj) {
3999                updateOomAdjLocked();
4000            }
4001            if (doLowMem) {
4002                doLowMemReportIfNeededLocked(app);
4003            }
4004        } else if (app.pid != pid) {
4005            // A new process has already been started.
4006            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4007                    + ") has died and restarted (pid " + app.pid + ").");
4008            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4009        } else if (DEBUG_PROCESSES) {
4010            Slog.d(TAG, "Received spurious death notification for thread "
4011                    + thread.asBinder());
4012        }
4013    }
4014
4015    /**
4016     * If a stack trace dump file is configured, dump process stack traces.
4017     * @param clearTraces causes the dump file to be erased prior to the new
4018     *    traces being written, if true; when false, the new traces will be
4019     *    appended to any existing file content.
4020     * @param firstPids of dalvik VM processes to dump stack traces for first
4021     * @param lastPids of dalvik VM processes to dump stack traces for last
4022     * @param nativeProcs optional list of native process names to dump stack crawls
4023     * @return file containing stack traces, or null if no dump file is configured
4024     */
4025    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4026            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4027        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4028        if (tracesPath == null || tracesPath.length() == 0) {
4029            return null;
4030        }
4031
4032        File tracesFile = new File(tracesPath);
4033        try {
4034            File tracesDir = tracesFile.getParentFile();
4035            if (!tracesDir.exists()) {
4036                tracesFile.mkdirs();
4037                if (!SELinux.restorecon(tracesDir)) {
4038                    return null;
4039                }
4040            }
4041            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4042
4043            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4044            tracesFile.createNewFile();
4045            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4046        } catch (IOException e) {
4047            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4048            return null;
4049        }
4050
4051        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4052        return tracesFile;
4053    }
4054
4055    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4056            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4057        // Use a FileObserver to detect when traces finish writing.
4058        // The order of traces is considered important to maintain for legibility.
4059        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4060            @Override
4061            public synchronized void onEvent(int event, String path) { notify(); }
4062        };
4063
4064        try {
4065            observer.startWatching();
4066
4067            // First collect all of the stacks of the most important pids.
4068            if (firstPids != null) {
4069                try {
4070                    int num = firstPids.size();
4071                    for (int i = 0; i < num; i++) {
4072                        synchronized (observer) {
4073                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4074                            observer.wait(200);  // Wait for write-close, give up after 200msec
4075                        }
4076                    }
4077                } catch (InterruptedException e) {
4078                    Log.wtf(TAG, e);
4079                }
4080            }
4081
4082            // Next collect the stacks of the native pids
4083            if (nativeProcs != null) {
4084                int[] pids = Process.getPidsForCommands(nativeProcs);
4085                if (pids != null) {
4086                    for (int pid : pids) {
4087                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4088                    }
4089                }
4090            }
4091
4092            // Lastly, measure CPU usage.
4093            if (processCpuTracker != null) {
4094                processCpuTracker.init();
4095                System.gc();
4096                processCpuTracker.update();
4097                try {
4098                    synchronized (processCpuTracker) {
4099                        processCpuTracker.wait(500); // measure over 1/2 second.
4100                    }
4101                } catch (InterruptedException e) {
4102                }
4103                processCpuTracker.update();
4104
4105                // We'll take the stack crawls of just the top apps using CPU.
4106                final int N = processCpuTracker.countWorkingStats();
4107                int numProcs = 0;
4108                for (int i=0; i<N && numProcs<5; i++) {
4109                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4110                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4111                        numProcs++;
4112                        try {
4113                            synchronized (observer) {
4114                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4115                                observer.wait(200);  // Wait for write-close, give up after 200msec
4116                            }
4117                        } catch (InterruptedException e) {
4118                            Log.wtf(TAG, e);
4119                        }
4120
4121                    }
4122                }
4123            }
4124        } finally {
4125            observer.stopWatching();
4126        }
4127    }
4128
4129    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4130        if (true || IS_USER_BUILD) {
4131            return;
4132        }
4133        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4134        if (tracesPath == null || tracesPath.length() == 0) {
4135            return;
4136        }
4137
4138        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4139        StrictMode.allowThreadDiskWrites();
4140        try {
4141            final File tracesFile = new File(tracesPath);
4142            final File tracesDir = tracesFile.getParentFile();
4143            final File tracesTmp = new File(tracesDir, "__tmp__");
4144            try {
4145                if (!tracesDir.exists()) {
4146                    tracesFile.mkdirs();
4147                    if (!SELinux.restorecon(tracesDir.getPath())) {
4148                        return;
4149                    }
4150                }
4151                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4152
4153                if (tracesFile.exists()) {
4154                    tracesTmp.delete();
4155                    tracesFile.renameTo(tracesTmp);
4156                }
4157                StringBuilder sb = new StringBuilder();
4158                Time tobj = new Time();
4159                tobj.set(System.currentTimeMillis());
4160                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4161                sb.append(": ");
4162                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4163                sb.append(" since ");
4164                sb.append(msg);
4165                FileOutputStream fos = new FileOutputStream(tracesFile);
4166                fos.write(sb.toString().getBytes());
4167                if (app == null) {
4168                    fos.write("\n*** No application process!".getBytes());
4169                }
4170                fos.close();
4171                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4172            } catch (IOException e) {
4173                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4174                return;
4175            }
4176
4177            if (app != null) {
4178                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4179                firstPids.add(app.pid);
4180                dumpStackTraces(tracesPath, firstPids, null, null, null);
4181            }
4182
4183            File lastTracesFile = null;
4184            File curTracesFile = null;
4185            for (int i=9; i>=0; i--) {
4186                String name = String.format(Locale.US, "slow%02d.txt", i);
4187                curTracesFile = new File(tracesDir, name);
4188                if (curTracesFile.exists()) {
4189                    if (lastTracesFile != null) {
4190                        curTracesFile.renameTo(lastTracesFile);
4191                    } else {
4192                        curTracesFile.delete();
4193                    }
4194                }
4195                lastTracesFile = curTracesFile;
4196            }
4197            tracesFile.renameTo(curTracesFile);
4198            if (tracesTmp.exists()) {
4199                tracesTmp.renameTo(tracesFile);
4200            }
4201        } finally {
4202            StrictMode.setThreadPolicy(oldPolicy);
4203        }
4204    }
4205
4206    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4207            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4208        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4209        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4210
4211        if (mController != null) {
4212            try {
4213                // 0 == continue, -1 = kill process immediately
4214                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4215                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4216            } catch (RemoteException e) {
4217                mController = null;
4218                Watchdog.getInstance().setActivityController(null);
4219            }
4220        }
4221
4222        long anrTime = SystemClock.uptimeMillis();
4223        if (MONITOR_CPU_USAGE) {
4224            updateCpuStatsNow();
4225        }
4226
4227        synchronized (this) {
4228            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4229            if (mShuttingDown) {
4230                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4231                return;
4232            } else if (app.notResponding) {
4233                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4234                return;
4235            } else if (app.crashing) {
4236                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4237                return;
4238            }
4239
4240            // In case we come through here for the same app before completing
4241            // this one, mark as anring now so we will bail out.
4242            app.notResponding = true;
4243
4244            // Log the ANR to the event log.
4245            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4246                    app.processName, app.info.flags, annotation);
4247
4248            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4249            firstPids.add(app.pid);
4250
4251            int parentPid = app.pid;
4252            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4253            if (parentPid != app.pid) firstPids.add(parentPid);
4254
4255            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4256
4257            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4258                ProcessRecord r = mLruProcesses.get(i);
4259                if (r != null && r.thread != null) {
4260                    int pid = r.pid;
4261                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4262                        if (r.persistent) {
4263                            firstPids.add(pid);
4264                        } else {
4265                            lastPids.put(pid, Boolean.TRUE);
4266                        }
4267                    }
4268                }
4269            }
4270        }
4271
4272        // Log the ANR to the main log.
4273        StringBuilder info = new StringBuilder();
4274        info.setLength(0);
4275        info.append("ANR in ").append(app.processName);
4276        if (activity != null && activity.shortComponentName != null) {
4277            info.append(" (").append(activity.shortComponentName).append(")");
4278        }
4279        info.append("\n");
4280        info.append("PID: ").append(app.pid).append("\n");
4281        if (annotation != null) {
4282            info.append("Reason: ").append(annotation).append("\n");
4283        }
4284        if (parent != null && parent != activity) {
4285            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4286        }
4287
4288        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4289
4290        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4291                NATIVE_STACKS_OF_INTEREST);
4292
4293        String cpuInfo = null;
4294        if (MONITOR_CPU_USAGE) {
4295            updateCpuStatsNow();
4296            synchronized (mProcessCpuThread) {
4297                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4298            }
4299            info.append(processCpuTracker.printCurrentLoad());
4300            info.append(cpuInfo);
4301        }
4302
4303        info.append(processCpuTracker.printCurrentState(anrTime));
4304
4305        Slog.e(TAG, info.toString());
4306        if (tracesFile == null) {
4307            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4308            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4309        }
4310
4311        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4312                cpuInfo, tracesFile, null);
4313
4314        if (mController != null) {
4315            try {
4316                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4317                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4318                if (res != 0) {
4319                    if (res < 0 && app.pid != MY_PID) {
4320                        Process.killProcess(app.pid);
4321                    } else {
4322                        synchronized (this) {
4323                            mServices.scheduleServiceTimeoutLocked(app);
4324                        }
4325                    }
4326                    return;
4327                }
4328            } catch (RemoteException e) {
4329                mController = null;
4330                Watchdog.getInstance().setActivityController(null);
4331            }
4332        }
4333
4334        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4335        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4336                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4337
4338        synchronized (this) {
4339            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4340                killUnneededProcessLocked(app, "background ANR");
4341                return;
4342            }
4343
4344            // Set the app's notResponding state, and look up the errorReportReceiver
4345            makeAppNotRespondingLocked(app,
4346                    activity != null ? activity.shortComponentName : null,
4347                    annotation != null ? "ANR " + annotation : "ANR",
4348                    info.toString());
4349
4350            // Bring up the infamous App Not Responding dialog
4351            Message msg = Message.obtain();
4352            HashMap<String, Object> map = new HashMap<String, Object>();
4353            msg.what = SHOW_NOT_RESPONDING_MSG;
4354            msg.obj = map;
4355            msg.arg1 = aboveSystem ? 1 : 0;
4356            map.put("app", app);
4357            if (activity != null) {
4358                map.put("activity", activity);
4359            }
4360
4361            mHandler.sendMessage(msg);
4362        }
4363    }
4364
4365    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4366        if (!mLaunchWarningShown) {
4367            mLaunchWarningShown = true;
4368            mHandler.post(new Runnable() {
4369                @Override
4370                public void run() {
4371                    synchronized (ActivityManagerService.this) {
4372                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4373                        d.show();
4374                        mHandler.postDelayed(new Runnable() {
4375                            @Override
4376                            public void run() {
4377                                synchronized (ActivityManagerService.this) {
4378                                    d.dismiss();
4379                                    mLaunchWarningShown = false;
4380                                }
4381                            }
4382                        }, 4000);
4383                    }
4384                }
4385            });
4386        }
4387    }
4388
4389    @Override
4390    public boolean clearApplicationUserData(final String packageName,
4391            final IPackageDataObserver observer, int userId) {
4392        enforceNotIsolatedCaller("clearApplicationUserData");
4393        int uid = Binder.getCallingUid();
4394        int pid = Binder.getCallingPid();
4395        userId = handleIncomingUser(pid, uid,
4396                userId, false, true, "clearApplicationUserData", null);
4397        long callingId = Binder.clearCallingIdentity();
4398        try {
4399            IPackageManager pm = AppGlobals.getPackageManager();
4400            int pkgUid = -1;
4401            synchronized(this) {
4402                try {
4403                    pkgUid = pm.getPackageUid(packageName, userId);
4404                } catch (RemoteException e) {
4405                }
4406                if (pkgUid == -1) {
4407                    Slog.w(TAG, "Invalid packageName: " + packageName);
4408                    if (observer != null) {
4409                        try {
4410                            observer.onRemoveCompleted(packageName, false);
4411                        } catch (RemoteException e) {
4412                            Slog.i(TAG, "Observer no longer exists.");
4413                        }
4414                    }
4415                    return false;
4416                }
4417                if (uid == pkgUid || checkComponentPermission(
4418                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4419                        pid, uid, -1, true)
4420                        == PackageManager.PERMISSION_GRANTED) {
4421                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4422                } else {
4423                    throw new SecurityException("PID " + pid + " does not have permission "
4424                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4425                                    + " of package " + packageName);
4426                }
4427            }
4428
4429            try {
4430                // Clear application user data
4431                pm.clearApplicationUserData(packageName, observer, userId);
4432
4433                // Remove all permissions granted from/to this package
4434                removeUriPermissionsForPackageLocked(packageName, userId, true);
4435
4436                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4437                        Uri.fromParts("package", packageName, null));
4438                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4439                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4440                        null, null, 0, null, null, null, false, false, userId);
4441            } catch (RemoteException e) {
4442            }
4443        } finally {
4444            Binder.restoreCallingIdentity(callingId);
4445        }
4446        return true;
4447    }
4448
4449    @Override
4450    public void killBackgroundProcesses(final String packageName, int userId) {
4451        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4452                != PackageManager.PERMISSION_GRANTED &&
4453                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4454                        != PackageManager.PERMISSION_GRANTED) {
4455            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4456                    + Binder.getCallingPid()
4457                    + ", uid=" + Binder.getCallingUid()
4458                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4459            Slog.w(TAG, msg);
4460            throw new SecurityException(msg);
4461        }
4462
4463        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4464                userId, true, true, "killBackgroundProcesses", null);
4465        long callingId = Binder.clearCallingIdentity();
4466        try {
4467            IPackageManager pm = AppGlobals.getPackageManager();
4468            synchronized(this) {
4469                int appId = -1;
4470                try {
4471                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4472                } catch (RemoteException e) {
4473                }
4474                if (appId == -1) {
4475                    Slog.w(TAG, "Invalid packageName: " + packageName);
4476                    return;
4477                }
4478                killPackageProcessesLocked(packageName, appId, userId,
4479                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4480            }
4481        } finally {
4482            Binder.restoreCallingIdentity(callingId);
4483        }
4484    }
4485
4486    @Override
4487    public void killAllBackgroundProcesses() {
4488        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4489                != PackageManager.PERMISSION_GRANTED) {
4490            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4491                    + Binder.getCallingPid()
4492                    + ", uid=" + Binder.getCallingUid()
4493                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4494            Slog.w(TAG, msg);
4495            throw new SecurityException(msg);
4496        }
4497
4498        long callingId = Binder.clearCallingIdentity();
4499        try {
4500            synchronized(this) {
4501                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4502                final int NP = mProcessNames.getMap().size();
4503                for (int ip=0; ip<NP; ip++) {
4504                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4505                    final int NA = apps.size();
4506                    for (int ia=0; ia<NA; ia++) {
4507                        ProcessRecord app = apps.valueAt(ia);
4508                        if (app.persistent) {
4509                            // we don't kill persistent processes
4510                            continue;
4511                        }
4512                        if (app.removed) {
4513                            procs.add(app);
4514                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4515                            app.removed = true;
4516                            procs.add(app);
4517                        }
4518                    }
4519                }
4520
4521                int N = procs.size();
4522                for (int i=0; i<N; i++) {
4523                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4524                }
4525                mAllowLowerMemLevel = true;
4526                updateOomAdjLocked();
4527                doLowMemReportIfNeededLocked(null);
4528            }
4529        } finally {
4530            Binder.restoreCallingIdentity(callingId);
4531        }
4532    }
4533
4534    @Override
4535    public void forceStopPackage(final String packageName, int userId) {
4536        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4537                != PackageManager.PERMISSION_GRANTED) {
4538            String msg = "Permission Denial: forceStopPackage() from pid="
4539                    + Binder.getCallingPid()
4540                    + ", uid=" + Binder.getCallingUid()
4541                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4542            Slog.w(TAG, msg);
4543            throw new SecurityException(msg);
4544        }
4545        final int callingPid = Binder.getCallingPid();
4546        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4547                userId, true, true, "forceStopPackage", null);
4548        long callingId = Binder.clearCallingIdentity();
4549        try {
4550            IPackageManager pm = AppGlobals.getPackageManager();
4551            synchronized(this) {
4552                int[] users = userId == UserHandle.USER_ALL
4553                        ? getUsersLocked() : new int[] { userId };
4554                for (int user : users) {
4555                    int pkgUid = -1;
4556                    try {
4557                        pkgUid = pm.getPackageUid(packageName, user);
4558                    } catch (RemoteException e) {
4559                    }
4560                    if (pkgUid == -1) {
4561                        Slog.w(TAG, "Invalid packageName: " + packageName);
4562                        continue;
4563                    }
4564                    try {
4565                        pm.setPackageStoppedState(packageName, true, user);
4566                    } catch (RemoteException e) {
4567                    } catch (IllegalArgumentException e) {
4568                        Slog.w(TAG, "Failed trying to unstop package "
4569                                + packageName + ": " + e);
4570                    }
4571                    if (isUserRunningLocked(user, false)) {
4572                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4573                    }
4574                }
4575            }
4576        } finally {
4577            Binder.restoreCallingIdentity(callingId);
4578        }
4579    }
4580
4581    /*
4582     * The pkg name and app id have to be specified.
4583     */
4584    @Override
4585    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4586        if (pkg == null) {
4587            return;
4588        }
4589        // Make sure the uid is valid.
4590        if (appid < 0) {
4591            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4592            return;
4593        }
4594        int callerUid = Binder.getCallingUid();
4595        // Only the system server can kill an application
4596        if (callerUid == Process.SYSTEM_UID) {
4597            // Post an aysnc message to kill the application
4598            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4599            msg.arg1 = appid;
4600            msg.arg2 = 0;
4601            Bundle bundle = new Bundle();
4602            bundle.putString("pkg", pkg);
4603            bundle.putString("reason", reason);
4604            msg.obj = bundle;
4605            mHandler.sendMessage(msg);
4606        } else {
4607            throw new SecurityException(callerUid + " cannot kill pkg: " +
4608                    pkg);
4609        }
4610    }
4611
4612    @Override
4613    public void closeSystemDialogs(String reason) {
4614        enforceNotIsolatedCaller("closeSystemDialogs");
4615
4616        final int pid = Binder.getCallingPid();
4617        final int uid = Binder.getCallingUid();
4618        final long origId = Binder.clearCallingIdentity();
4619        try {
4620            synchronized (this) {
4621                // Only allow this from foreground processes, so that background
4622                // applications can't abuse it to prevent system UI from being shown.
4623                if (uid >= Process.FIRST_APPLICATION_UID) {
4624                    ProcessRecord proc;
4625                    synchronized (mPidsSelfLocked) {
4626                        proc = mPidsSelfLocked.get(pid);
4627                    }
4628                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4629                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4630                                + " from background process " + proc);
4631                        return;
4632                    }
4633                }
4634                closeSystemDialogsLocked(reason);
4635            }
4636        } finally {
4637            Binder.restoreCallingIdentity(origId);
4638        }
4639    }
4640
4641    void closeSystemDialogsLocked(String reason) {
4642        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4643        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4644                | Intent.FLAG_RECEIVER_FOREGROUND);
4645        if (reason != null) {
4646            intent.putExtra("reason", reason);
4647        }
4648        mWindowManager.closeSystemDialogs(reason);
4649
4650        mStackSupervisor.closeSystemDialogsLocked();
4651
4652        broadcastIntentLocked(null, null, intent, null,
4653                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4654                Process.SYSTEM_UID, UserHandle.USER_ALL);
4655    }
4656
4657    @Override
4658    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4659        enforceNotIsolatedCaller("getProcessMemoryInfo");
4660        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4661        for (int i=pids.length-1; i>=0; i--) {
4662            ProcessRecord proc;
4663            int oomAdj;
4664            synchronized (this) {
4665                synchronized (mPidsSelfLocked) {
4666                    proc = mPidsSelfLocked.get(pids[i]);
4667                    oomAdj = proc != null ? proc.setAdj : 0;
4668                }
4669            }
4670            infos[i] = new Debug.MemoryInfo();
4671            Debug.getMemoryInfo(pids[i], infos[i]);
4672            if (proc != null) {
4673                synchronized (this) {
4674                    if (proc.thread != null && proc.setAdj == oomAdj) {
4675                        // Record this for posterity if the process has been stable.
4676                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4677                                infos[i].getTotalUss(), false, proc.pkgList);
4678                    }
4679                }
4680            }
4681        }
4682        return infos;
4683    }
4684
4685    @Override
4686    public long[] getProcessPss(int[] pids) {
4687        enforceNotIsolatedCaller("getProcessPss");
4688        long[] pss = new long[pids.length];
4689        for (int i=pids.length-1; i>=0; i--) {
4690            ProcessRecord proc;
4691            int oomAdj;
4692            synchronized (this) {
4693                synchronized (mPidsSelfLocked) {
4694                    proc = mPidsSelfLocked.get(pids[i]);
4695                    oomAdj = proc != null ? proc.setAdj : 0;
4696                }
4697            }
4698            long[] tmpUss = new long[1];
4699            pss[i] = Debug.getPss(pids[i], tmpUss);
4700            if (proc != null) {
4701                synchronized (this) {
4702                    if (proc.thread != null && proc.setAdj == oomAdj) {
4703                        // Record this for posterity if the process has been stable.
4704                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4705                    }
4706                }
4707            }
4708        }
4709        return pss;
4710    }
4711
4712    @Override
4713    public void killApplicationProcess(String processName, int uid) {
4714        if (processName == null) {
4715            return;
4716        }
4717
4718        int callerUid = Binder.getCallingUid();
4719        // Only the system server can kill an application
4720        if (callerUid == Process.SYSTEM_UID) {
4721            synchronized (this) {
4722                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4723                if (app != null && app.thread != null) {
4724                    try {
4725                        app.thread.scheduleSuicide();
4726                    } catch (RemoteException e) {
4727                        // If the other end already died, then our work here is done.
4728                    }
4729                } else {
4730                    Slog.w(TAG, "Process/uid not found attempting kill of "
4731                            + processName + " / " + uid);
4732                }
4733            }
4734        } else {
4735            throw new SecurityException(callerUid + " cannot kill app process: " +
4736                    processName);
4737        }
4738    }
4739
4740    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4741        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4742                false, true, false, false, UserHandle.getUserId(uid), reason);
4743        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4744                Uri.fromParts("package", packageName, null));
4745        if (!mProcessesReady) {
4746            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4747                    | Intent.FLAG_RECEIVER_FOREGROUND);
4748        }
4749        intent.putExtra(Intent.EXTRA_UID, uid);
4750        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4751        broadcastIntentLocked(null, null, intent,
4752                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4753                false, false,
4754                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4755    }
4756
4757    private void forceStopUserLocked(int userId, String reason) {
4758        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4759        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4760        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4761                | Intent.FLAG_RECEIVER_FOREGROUND);
4762        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4763        broadcastIntentLocked(null, null, intent,
4764                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4765                false, false,
4766                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4767    }
4768
4769    private final boolean killPackageProcessesLocked(String packageName, int appId,
4770            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4771            boolean doit, boolean evenPersistent, String reason) {
4772        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4773
4774        // Remove all processes this package may have touched: all with the
4775        // same UID (except for the system or root user), and all whose name
4776        // matches the package name.
4777        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4778        final int NP = mProcessNames.getMap().size();
4779        for (int ip=0; ip<NP; ip++) {
4780            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4781            final int NA = apps.size();
4782            for (int ia=0; ia<NA; ia++) {
4783                ProcessRecord app = apps.valueAt(ia);
4784                if (app.persistent && !evenPersistent) {
4785                    // we don't kill persistent processes
4786                    continue;
4787                }
4788                if (app.removed) {
4789                    if (doit) {
4790                        procs.add(app);
4791                    }
4792                    continue;
4793                }
4794
4795                // Skip process if it doesn't meet our oom adj requirement.
4796                if (app.setAdj < minOomAdj) {
4797                    continue;
4798                }
4799
4800                // If no package is specified, we call all processes under the
4801                // give user id.
4802                if (packageName == null) {
4803                    if (app.userId != userId) {
4804                        continue;
4805                    }
4806                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4807                        continue;
4808                    }
4809                // Package has been specified, we want to hit all processes
4810                // that match it.  We need to qualify this by the processes
4811                // that are running under the specified app and user ID.
4812                } else {
4813                    if (UserHandle.getAppId(app.uid) != appId) {
4814                        continue;
4815                    }
4816                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4817                        continue;
4818                    }
4819                    if (!app.pkgList.containsKey(packageName)) {
4820                        continue;
4821                    }
4822                }
4823
4824                // Process has passed all conditions, kill it!
4825                if (!doit) {
4826                    return true;
4827                }
4828                app.removed = true;
4829                procs.add(app);
4830            }
4831        }
4832
4833        int N = procs.size();
4834        for (int i=0; i<N; i++) {
4835            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4836        }
4837        updateOomAdjLocked();
4838        return N > 0;
4839    }
4840
4841    private final boolean forceStopPackageLocked(String name, int appId,
4842            boolean callerWillRestart, boolean purgeCache, boolean doit,
4843            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4844        int i;
4845        int N;
4846
4847        if (userId == UserHandle.USER_ALL && name == null) {
4848            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4849        }
4850
4851        if (appId < 0 && name != null) {
4852            try {
4853                appId = UserHandle.getAppId(
4854                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4855            } catch (RemoteException e) {
4856            }
4857        }
4858
4859        if (doit) {
4860            if (name != null) {
4861                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4862                        + " user=" + userId + ": " + reason);
4863            } else {
4864                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4865            }
4866
4867            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4868            for (int ip=pmap.size()-1; ip>=0; ip--) {
4869                SparseArray<Long> ba = pmap.valueAt(ip);
4870                for (i=ba.size()-1; i>=0; i--) {
4871                    boolean remove = false;
4872                    final int entUid = ba.keyAt(i);
4873                    if (name != null) {
4874                        if (userId == UserHandle.USER_ALL) {
4875                            if (UserHandle.getAppId(entUid) == appId) {
4876                                remove = true;
4877                            }
4878                        } else {
4879                            if (entUid == UserHandle.getUid(userId, appId)) {
4880                                remove = true;
4881                            }
4882                        }
4883                    } else if (UserHandle.getUserId(entUid) == userId) {
4884                        remove = true;
4885                    }
4886                    if (remove) {
4887                        ba.removeAt(i);
4888                    }
4889                }
4890                if (ba.size() == 0) {
4891                    pmap.removeAt(ip);
4892                }
4893            }
4894        }
4895
4896        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4897                -100, callerWillRestart, true, doit, evenPersistent,
4898                name == null ? ("stop user " + userId) : ("stop " + name));
4899
4900        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4901            if (!doit) {
4902                return true;
4903            }
4904            didSomething = true;
4905        }
4906
4907        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4908            if (!doit) {
4909                return true;
4910            }
4911            didSomething = true;
4912        }
4913
4914        if (name == null) {
4915            // Remove all sticky broadcasts from this user.
4916            mStickyBroadcasts.remove(userId);
4917        }
4918
4919        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4920        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4921                userId, providers)) {
4922            if (!doit) {
4923                return true;
4924            }
4925            didSomething = true;
4926        }
4927        N = providers.size();
4928        for (i=0; i<N; i++) {
4929            removeDyingProviderLocked(null, providers.get(i), true);
4930        }
4931
4932        // Remove transient permissions granted from/to this package/user
4933        removeUriPermissionsForPackageLocked(name, userId, false);
4934
4935        if (name == null || uninstalling) {
4936            // Remove pending intents.  For now we only do this when force
4937            // stopping users, because we have some problems when doing this
4938            // for packages -- app widgets are not currently cleaned up for
4939            // such packages, so they can be left with bad pending intents.
4940            if (mIntentSenderRecords.size() > 0) {
4941                Iterator<WeakReference<PendingIntentRecord>> it
4942                        = mIntentSenderRecords.values().iterator();
4943                while (it.hasNext()) {
4944                    WeakReference<PendingIntentRecord> wpir = it.next();
4945                    if (wpir == null) {
4946                        it.remove();
4947                        continue;
4948                    }
4949                    PendingIntentRecord pir = wpir.get();
4950                    if (pir == null) {
4951                        it.remove();
4952                        continue;
4953                    }
4954                    if (name == null) {
4955                        // Stopping user, remove all objects for the user.
4956                        if (pir.key.userId != userId) {
4957                            // Not the same user, skip it.
4958                            continue;
4959                        }
4960                    } else {
4961                        if (UserHandle.getAppId(pir.uid) != appId) {
4962                            // Different app id, skip it.
4963                            continue;
4964                        }
4965                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4966                            // Different user, skip it.
4967                            continue;
4968                        }
4969                        if (!pir.key.packageName.equals(name)) {
4970                            // Different package, skip it.
4971                            continue;
4972                        }
4973                    }
4974                    if (!doit) {
4975                        return true;
4976                    }
4977                    didSomething = true;
4978                    it.remove();
4979                    pir.canceled = true;
4980                    if (pir.key.activity != null) {
4981                        pir.key.activity.pendingResults.remove(pir.ref);
4982                    }
4983                }
4984            }
4985        }
4986
4987        if (doit) {
4988            if (purgeCache && name != null) {
4989                AttributeCache ac = AttributeCache.instance();
4990                if (ac != null) {
4991                    ac.removePackage(name);
4992                }
4993            }
4994            if (mBooted) {
4995                mStackSupervisor.resumeTopActivitiesLocked();
4996                mStackSupervisor.scheduleIdleLocked();
4997            }
4998        }
4999
5000        return didSomething;
5001    }
5002
5003    private final boolean removeProcessLocked(ProcessRecord app,
5004            boolean callerWillRestart, boolean allowRestart, String reason) {
5005        final String name = app.processName;
5006        final int uid = app.uid;
5007        if (DEBUG_PROCESSES) Slog.d(
5008            TAG, "Force removing proc " + app.toShortString() + " (" + name
5009            + "/" + uid + ")");
5010
5011        mProcessNames.remove(name, uid);
5012        mIsolatedProcesses.remove(app.uid);
5013        if (mHeavyWeightProcess == app) {
5014            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5015                    mHeavyWeightProcess.userId, 0));
5016            mHeavyWeightProcess = null;
5017        }
5018        boolean needRestart = false;
5019        if (app.pid > 0 && app.pid != MY_PID) {
5020            int pid = app.pid;
5021            synchronized (mPidsSelfLocked) {
5022                mPidsSelfLocked.remove(pid);
5023                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5024            }
5025            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5026                    app.processName, app.info.uid);
5027            if (app.isolated) {
5028                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5029            }
5030            killUnneededProcessLocked(app, reason);
5031            handleAppDiedLocked(app, true, allowRestart);
5032            removeLruProcessLocked(app);
5033
5034            if (app.persistent && !app.isolated) {
5035                if (!callerWillRestart) {
5036                    addAppLocked(app.info, false);
5037                } else {
5038                    needRestart = true;
5039                }
5040            }
5041        } else {
5042            mRemovedProcesses.add(app);
5043        }
5044
5045        return needRestart;
5046    }
5047
5048    private final void processStartTimedOutLocked(ProcessRecord app) {
5049        final int pid = app.pid;
5050        boolean gone = false;
5051        synchronized (mPidsSelfLocked) {
5052            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5053            if (knownApp != null && knownApp.thread == null) {
5054                mPidsSelfLocked.remove(pid);
5055                gone = true;
5056            }
5057        }
5058
5059        if (gone) {
5060            Slog.w(TAG, "Process " + app + " failed to attach");
5061            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5062                    pid, app.uid, app.processName);
5063            mProcessNames.remove(app.processName, app.uid);
5064            mIsolatedProcesses.remove(app.uid);
5065            if (mHeavyWeightProcess == app) {
5066                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5067                        mHeavyWeightProcess.userId, 0));
5068                mHeavyWeightProcess = null;
5069            }
5070            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5071                    app.processName, app.info.uid);
5072            if (app.isolated) {
5073                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5074            }
5075            // Take care of any launching providers waiting for this process.
5076            checkAppInLaunchingProvidersLocked(app, true);
5077            // Take care of any services that are waiting for the process.
5078            mServices.processStartTimedOutLocked(app);
5079            killUnneededProcessLocked(app, "start timeout");
5080            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5081                Slog.w(TAG, "Unattached app died before backup, skipping");
5082                try {
5083                    IBackupManager bm = IBackupManager.Stub.asInterface(
5084                            ServiceManager.getService(Context.BACKUP_SERVICE));
5085                    bm.agentDisconnected(app.info.packageName);
5086                } catch (RemoteException e) {
5087                    // Can't happen; the backup manager is local
5088                }
5089            }
5090            if (isPendingBroadcastProcessLocked(pid)) {
5091                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5092                skipPendingBroadcastLocked(pid);
5093            }
5094        } else {
5095            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5096        }
5097    }
5098
5099    private final boolean attachApplicationLocked(IApplicationThread thread,
5100            int pid) {
5101
5102        // Find the application record that is being attached...  either via
5103        // the pid if we are running in multiple processes, or just pull the
5104        // next app record if we are emulating process with anonymous threads.
5105        ProcessRecord app;
5106        if (pid != MY_PID && pid >= 0) {
5107            synchronized (mPidsSelfLocked) {
5108                app = mPidsSelfLocked.get(pid);
5109            }
5110        } else {
5111            app = null;
5112        }
5113
5114        if (app == null) {
5115            Slog.w(TAG, "No pending application record for pid " + pid
5116                    + " (IApplicationThread " + thread + "); dropping process");
5117            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5118            if (pid > 0 && pid != MY_PID) {
5119                Process.killProcessQuiet(pid);
5120            } else {
5121                try {
5122                    thread.scheduleExit();
5123                } catch (Exception e) {
5124                    // Ignore exceptions.
5125                }
5126            }
5127            return false;
5128        }
5129
5130        // If this application record is still attached to a previous
5131        // process, clean it up now.
5132        if (app.thread != null) {
5133            handleAppDiedLocked(app, true, true);
5134        }
5135
5136        // Tell the process all about itself.
5137
5138        if (localLOGV) Slog.v(
5139                TAG, "Binding process pid " + pid + " to record " + app);
5140
5141        final String processName = app.processName;
5142        try {
5143            AppDeathRecipient adr = new AppDeathRecipient(
5144                    app, pid, thread);
5145            thread.asBinder().linkToDeath(adr, 0);
5146            app.deathRecipient = adr;
5147        } catch (RemoteException e) {
5148            app.resetPackageList(mProcessStats);
5149            startProcessLocked(app, "link fail", processName);
5150            return false;
5151        }
5152
5153        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5154
5155        app.makeActive(thread, mProcessStats);
5156        app.curAdj = app.setAdj = -100;
5157        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5158        app.forcingToForeground = null;
5159        updateProcessForegroundLocked(app, false, false);
5160        app.hasShownUi = false;
5161        app.debugging = false;
5162        app.cached = false;
5163
5164        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5165
5166        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5167        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5168
5169        if (!normalMode) {
5170            Slog.i(TAG, "Launching preboot mode app: " + app);
5171        }
5172
5173        if (localLOGV) Slog.v(
5174            TAG, "New app record " + app
5175            + " thread=" + thread.asBinder() + " pid=" + pid);
5176        try {
5177            int testMode = IApplicationThread.DEBUG_OFF;
5178            if (mDebugApp != null && mDebugApp.equals(processName)) {
5179                testMode = mWaitForDebugger
5180                    ? IApplicationThread.DEBUG_WAIT
5181                    : IApplicationThread.DEBUG_ON;
5182                app.debugging = true;
5183                if (mDebugTransient) {
5184                    mDebugApp = mOrigDebugApp;
5185                    mWaitForDebugger = mOrigWaitForDebugger;
5186                }
5187            }
5188            String profileFile = app.instrumentationProfileFile;
5189            ParcelFileDescriptor profileFd = null;
5190            boolean profileAutoStop = false;
5191            if (mProfileApp != null && mProfileApp.equals(processName)) {
5192                mProfileProc = app;
5193                profileFile = mProfileFile;
5194                profileFd = mProfileFd;
5195                profileAutoStop = mAutoStopProfiler;
5196            }
5197            boolean enableOpenGlTrace = false;
5198            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5199                enableOpenGlTrace = true;
5200                mOpenGlTraceApp = null;
5201            }
5202
5203            // If the app is being launched for restore or full backup, set it up specially
5204            boolean isRestrictedBackupMode = false;
5205            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5206                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5207                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5208                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5209            }
5210
5211            ensurePackageDexOpt(app.instrumentationInfo != null
5212                    ? app.instrumentationInfo.packageName
5213                    : app.info.packageName);
5214            if (app.instrumentationClass != null) {
5215                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5216            }
5217            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5218                    + processName + " with config " + mConfiguration);
5219            ApplicationInfo appInfo = app.instrumentationInfo != null
5220                    ? app.instrumentationInfo : app.info;
5221            app.compat = compatibilityInfoForPackageLocked(appInfo);
5222            if (profileFd != null) {
5223                profileFd = profileFd.dup();
5224            }
5225            thread.bindApplication(processName, appInfo, providers,
5226                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5227                    app.instrumentationArguments, app.instrumentationWatcher,
5228                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5229                    isRestrictedBackupMode || !normalMode, app.persistent,
5230                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5231                    mCoreSettingsObserver.getCoreSettingsLocked());
5232            updateLruProcessLocked(app, false, null);
5233            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5234        } catch (Exception e) {
5235            // todo: Yikes!  What should we do?  For now we will try to
5236            // start another process, but that could easily get us in
5237            // an infinite loop of restarting processes...
5238            Slog.w(TAG, "Exception thrown during bind!", e);
5239
5240            app.resetPackageList(mProcessStats);
5241            app.unlinkDeathRecipient();
5242            startProcessLocked(app, "bind fail", processName);
5243            return false;
5244        }
5245
5246        // Remove this record from the list of starting applications.
5247        mPersistentStartingProcesses.remove(app);
5248        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5249                "Attach application locked removing on hold: " + app);
5250        mProcessesOnHold.remove(app);
5251
5252        boolean badApp = false;
5253        boolean didSomething = false;
5254
5255        // See if the top visible activity is waiting to run in this process...
5256        if (normalMode) {
5257            try {
5258                if (mStackSupervisor.attachApplicationLocked(app)) {
5259                    didSomething = true;
5260                }
5261            } catch (Exception e) {
5262                badApp = true;
5263            }
5264        }
5265
5266        // Find any services that should be running in this process...
5267        if (!badApp) {
5268            try {
5269                didSomething |= mServices.attachApplicationLocked(app, processName);
5270            } catch (Exception e) {
5271                badApp = true;
5272            }
5273        }
5274
5275        // Check if a next-broadcast receiver is in this process...
5276        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5277            try {
5278                didSomething |= sendPendingBroadcastsLocked(app);
5279            } catch (Exception e) {
5280                // If the app died trying to launch the receiver we declare it 'bad'
5281                badApp = true;
5282            }
5283        }
5284
5285        // Check whether the next backup agent is in this process...
5286        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5287            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5288            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5289            try {
5290                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5291                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5292                        mBackupTarget.backupMode);
5293            } catch (Exception e) {
5294                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5295                e.printStackTrace();
5296            }
5297        }
5298
5299        if (badApp) {
5300            // todo: Also need to kill application to deal with all
5301            // kinds of exceptions.
5302            handleAppDiedLocked(app, false, true);
5303            return false;
5304        }
5305
5306        if (!didSomething) {
5307            updateOomAdjLocked();
5308        }
5309
5310        return true;
5311    }
5312
5313    @Override
5314    public final void attachApplication(IApplicationThread thread) {
5315        synchronized (this) {
5316            int callingPid = Binder.getCallingPid();
5317            final long origId = Binder.clearCallingIdentity();
5318            attachApplicationLocked(thread, callingPid);
5319            Binder.restoreCallingIdentity(origId);
5320        }
5321    }
5322
5323    @Override
5324    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5325        final long origId = Binder.clearCallingIdentity();
5326        synchronized (this) {
5327            ActivityStack stack = ActivityRecord.getStackLocked(token);
5328            if (stack != null) {
5329                ActivityRecord r =
5330                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5331                if (stopProfiling) {
5332                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5333                        try {
5334                            mProfileFd.close();
5335                        } catch (IOException e) {
5336                        }
5337                        clearProfilerLocked();
5338                    }
5339                }
5340            }
5341        }
5342        Binder.restoreCallingIdentity(origId);
5343    }
5344
5345    void enableScreenAfterBoot() {
5346        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5347                SystemClock.uptimeMillis());
5348        mWindowManager.enableScreenAfterBoot();
5349
5350        synchronized (this) {
5351            updateEventDispatchingLocked();
5352        }
5353    }
5354
5355    @Override
5356    public void showBootMessage(final CharSequence msg, final boolean always) {
5357        enforceNotIsolatedCaller("showBootMessage");
5358        mWindowManager.showBootMessage(msg, always);
5359    }
5360
5361    @Override
5362    public void dismissKeyguardOnNextActivity() {
5363        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5364        final long token = Binder.clearCallingIdentity();
5365        try {
5366            synchronized (this) {
5367                if (DEBUG_LOCKSCREEN) logLockScreen("");
5368                if (mLockScreenShown) {
5369                    mLockScreenShown = false;
5370                    comeOutOfSleepIfNeededLocked();
5371                }
5372                mStackSupervisor.setDismissKeyguard(true);
5373            }
5374        } finally {
5375            Binder.restoreCallingIdentity(token);
5376        }
5377    }
5378
5379    final void finishBooting() {
5380        // Register receivers to handle package update events
5381        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5382
5383        synchronized (this) {
5384            // Ensure that any processes we had put on hold are now started
5385            // up.
5386            final int NP = mProcessesOnHold.size();
5387            if (NP > 0) {
5388                ArrayList<ProcessRecord> procs =
5389                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5390                for (int ip=0; ip<NP; ip++) {
5391                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5392                            + procs.get(ip));
5393                    startProcessLocked(procs.get(ip), "on-hold", null);
5394                }
5395            }
5396
5397            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5398                // Start looking for apps that are abusing wake locks.
5399                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5400                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5401                // Tell anyone interested that we are done booting!
5402                SystemProperties.set("sys.boot_completed", "1");
5403                SystemProperties.set("dev.bootcomplete", "1");
5404                for (int i=0; i<mStartedUsers.size(); i++) {
5405                    UserStartedState uss = mStartedUsers.valueAt(i);
5406                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5407                        uss.mState = UserStartedState.STATE_RUNNING;
5408                        final int userId = mStartedUsers.keyAt(i);
5409                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5410                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5411                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5412                        broadcastIntentLocked(null, null, intent, null,
5413                                new IIntentReceiver.Stub() {
5414                                    @Override
5415                                    public void performReceive(Intent intent, int resultCode,
5416                                            String data, Bundle extras, boolean ordered,
5417                                            boolean sticky, int sendingUser) {
5418                                        synchronized (ActivityManagerService.this) {
5419                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5420                                                    true, false);
5421                                        }
5422                                    }
5423                                },
5424                                0, null, null,
5425                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5426                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5427                                userId);
5428                    }
5429                }
5430                scheduleStartProfilesLocked();
5431            }
5432        }
5433    }
5434
5435    final void ensureBootCompleted() {
5436        boolean booting;
5437        boolean enableScreen;
5438        synchronized (this) {
5439            booting = mBooting;
5440            mBooting = false;
5441            enableScreen = !mBooted;
5442            mBooted = true;
5443        }
5444
5445        if (booting) {
5446            finishBooting();
5447        }
5448
5449        if (enableScreen) {
5450            enableScreenAfterBoot();
5451        }
5452    }
5453
5454    @Override
5455    public final void activityResumed(IBinder token) {
5456        final long origId = Binder.clearCallingIdentity();
5457        synchronized(this) {
5458            ActivityStack stack = ActivityRecord.getStackLocked(token);
5459            if (stack != null) {
5460                ActivityRecord.activityResumedLocked(token);
5461            }
5462        }
5463        Binder.restoreCallingIdentity(origId);
5464    }
5465
5466    @Override
5467    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5468        final long origId = Binder.clearCallingIdentity();
5469        synchronized(this) {
5470            ActivityStack stack = ActivityRecord.getStackLocked(token);
5471            if (stack != null) {
5472                stack.activityPausedLocked(token, false, persistentState);
5473            }
5474        }
5475        Binder.restoreCallingIdentity(origId);
5476    }
5477
5478    @Override
5479    public final void activityStopped(IBinder token, Bundle icicle,
5480            PersistableBundle persistentState, CharSequence description) {
5481        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5482
5483        // Refuse possible leaked file descriptors
5484        if (icicle != null && icicle.hasFileDescriptors()) {
5485            throw new IllegalArgumentException("File descriptors passed in Bundle");
5486        }
5487
5488        final long origId = Binder.clearCallingIdentity();
5489
5490        synchronized (this) {
5491            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5492            if (r != null) {
5493                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5494            }
5495        }
5496
5497        trimApplications();
5498
5499        Binder.restoreCallingIdentity(origId);
5500    }
5501
5502    @Override
5503    public final void activityDestroyed(IBinder token) {
5504        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5505        synchronized (this) {
5506            ActivityStack stack = ActivityRecord.getStackLocked(token);
5507            if (stack != null) {
5508                stack.activityDestroyedLocked(token);
5509            }
5510        }
5511    }
5512
5513    @Override
5514    public String getCallingPackage(IBinder token) {
5515        synchronized (this) {
5516            ActivityRecord r = getCallingRecordLocked(token);
5517            return r != null ? r.info.packageName : null;
5518        }
5519    }
5520
5521    @Override
5522    public ComponentName getCallingActivity(IBinder token) {
5523        synchronized (this) {
5524            ActivityRecord r = getCallingRecordLocked(token);
5525            return r != null ? r.intent.getComponent() : null;
5526        }
5527    }
5528
5529    private ActivityRecord getCallingRecordLocked(IBinder token) {
5530        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5531        if (r == null) {
5532            return null;
5533        }
5534        return r.resultTo;
5535    }
5536
5537    @Override
5538    public ComponentName getActivityClassForToken(IBinder token) {
5539        synchronized(this) {
5540            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5541            if (r == null) {
5542                return null;
5543            }
5544            return r.intent.getComponent();
5545        }
5546    }
5547
5548    @Override
5549    public String getPackageForToken(IBinder token) {
5550        synchronized(this) {
5551            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5552            if (r == null) {
5553                return null;
5554            }
5555            return r.packageName;
5556        }
5557    }
5558
5559    @Override
5560    public IIntentSender getIntentSender(int type,
5561            String packageName, IBinder token, String resultWho,
5562            int requestCode, Intent[] intents, String[] resolvedTypes,
5563            int flags, Bundle options, int userId) {
5564        enforceNotIsolatedCaller("getIntentSender");
5565        // Refuse possible leaked file descriptors
5566        if (intents != null) {
5567            if (intents.length < 1) {
5568                throw new IllegalArgumentException("Intents array length must be >= 1");
5569            }
5570            for (int i=0; i<intents.length; i++) {
5571                Intent intent = intents[i];
5572                if (intent != null) {
5573                    if (intent.hasFileDescriptors()) {
5574                        throw new IllegalArgumentException("File descriptors passed in Intent");
5575                    }
5576                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5577                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5578                        throw new IllegalArgumentException(
5579                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5580                    }
5581                    intents[i] = new Intent(intent);
5582                }
5583            }
5584            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5585                throw new IllegalArgumentException(
5586                        "Intent array length does not match resolvedTypes length");
5587            }
5588        }
5589        if (options != null) {
5590            if (options.hasFileDescriptors()) {
5591                throw new IllegalArgumentException("File descriptors passed in options");
5592            }
5593        }
5594
5595        synchronized(this) {
5596            int callingUid = Binder.getCallingUid();
5597            int origUserId = userId;
5598            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5599                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5600                    "getIntentSender", null);
5601            if (origUserId == UserHandle.USER_CURRENT) {
5602                // We don't want to evaluate this until the pending intent is
5603                // actually executed.  However, we do want to always do the
5604                // security checking for it above.
5605                userId = UserHandle.USER_CURRENT;
5606            }
5607            try {
5608                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5609                    int uid = AppGlobals.getPackageManager()
5610                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5611                    if (!UserHandle.isSameApp(callingUid, uid)) {
5612                        String msg = "Permission Denial: getIntentSender() from pid="
5613                            + Binder.getCallingPid()
5614                            + ", uid=" + Binder.getCallingUid()
5615                            + ", (need uid=" + uid + ")"
5616                            + " is not allowed to send as package " + packageName;
5617                        Slog.w(TAG, msg);
5618                        throw new SecurityException(msg);
5619                    }
5620                }
5621
5622                return getIntentSenderLocked(type, packageName, callingUid, userId,
5623                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5624
5625            } catch (RemoteException e) {
5626                throw new SecurityException(e);
5627            }
5628        }
5629    }
5630
5631    IIntentSender getIntentSenderLocked(int type, String packageName,
5632            int callingUid, int userId, IBinder token, String resultWho,
5633            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5634            Bundle options) {
5635        if (DEBUG_MU)
5636            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5637        ActivityRecord activity = null;
5638        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5639            activity = ActivityRecord.isInStackLocked(token);
5640            if (activity == null) {
5641                return null;
5642            }
5643            if (activity.finishing) {
5644                return null;
5645            }
5646        }
5647
5648        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5649        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5650        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5651        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5652                |PendingIntent.FLAG_UPDATE_CURRENT);
5653
5654        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5655                type, packageName, activity, resultWho,
5656                requestCode, intents, resolvedTypes, flags, options, userId);
5657        WeakReference<PendingIntentRecord> ref;
5658        ref = mIntentSenderRecords.get(key);
5659        PendingIntentRecord rec = ref != null ? ref.get() : null;
5660        if (rec != null) {
5661            if (!cancelCurrent) {
5662                if (updateCurrent) {
5663                    if (rec.key.requestIntent != null) {
5664                        rec.key.requestIntent.replaceExtras(intents != null ?
5665                                intents[intents.length - 1] : null);
5666                    }
5667                    if (intents != null) {
5668                        intents[intents.length-1] = rec.key.requestIntent;
5669                        rec.key.allIntents = intents;
5670                        rec.key.allResolvedTypes = resolvedTypes;
5671                    } else {
5672                        rec.key.allIntents = null;
5673                        rec.key.allResolvedTypes = null;
5674                    }
5675                }
5676                return rec;
5677            }
5678            rec.canceled = true;
5679            mIntentSenderRecords.remove(key);
5680        }
5681        if (noCreate) {
5682            return rec;
5683        }
5684        rec = new PendingIntentRecord(this, key, callingUid);
5685        mIntentSenderRecords.put(key, rec.ref);
5686        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5687            if (activity.pendingResults == null) {
5688                activity.pendingResults
5689                        = new HashSet<WeakReference<PendingIntentRecord>>();
5690            }
5691            activity.pendingResults.add(rec.ref);
5692        }
5693        return rec;
5694    }
5695
5696    @Override
5697    public void cancelIntentSender(IIntentSender sender) {
5698        if (!(sender instanceof PendingIntentRecord)) {
5699            return;
5700        }
5701        synchronized(this) {
5702            PendingIntentRecord rec = (PendingIntentRecord)sender;
5703            try {
5704                int uid = AppGlobals.getPackageManager()
5705                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5706                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5707                    String msg = "Permission Denial: cancelIntentSender() from pid="
5708                        + Binder.getCallingPid()
5709                        + ", uid=" + Binder.getCallingUid()
5710                        + " is not allowed to cancel packges "
5711                        + rec.key.packageName;
5712                    Slog.w(TAG, msg);
5713                    throw new SecurityException(msg);
5714                }
5715            } catch (RemoteException e) {
5716                throw new SecurityException(e);
5717            }
5718            cancelIntentSenderLocked(rec, true);
5719        }
5720    }
5721
5722    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5723        rec.canceled = true;
5724        mIntentSenderRecords.remove(rec.key);
5725        if (cleanActivity && rec.key.activity != null) {
5726            rec.key.activity.pendingResults.remove(rec.ref);
5727        }
5728    }
5729
5730    @Override
5731    public String getPackageForIntentSender(IIntentSender pendingResult) {
5732        if (!(pendingResult instanceof PendingIntentRecord)) {
5733            return null;
5734        }
5735        try {
5736            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5737            return res.key.packageName;
5738        } catch (ClassCastException e) {
5739        }
5740        return null;
5741    }
5742
5743    @Override
5744    public int getUidForIntentSender(IIntentSender sender) {
5745        if (sender instanceof PendingIntentRecord) {
5746            try {
5747                PendingIntentRecord res = (PendingIntentRecord)sender;
5748                return res.uid;
5749            } catch (ClassCastException e) {
5750            }
5751        }
5752        return -1;
5753    }
5754
5755    @Override
5756    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5757        if (!(pendingResult instanceof PendingIntentRecord)) {
5758            return false;
5759        }
5760        try {
5761            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5762            if (res.key.allIntents == null) {
5763                return false;
5764            }
5765            for (int i=0; i<res.key.allIntents.length; i++) {
5766                Intent intent = res.key.allIntents[i];
5767                if (intent.getPackage() != null && intent.getComponent() != null) {
5768                    return false;
5769                }
5770            }
5771            return true;
5772        } catch (ClassCastException e) {
5773        }
5774        return false;
5775    }
5776
5777    @Override
5778    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5779        if (!(pendingResult instanceof PendingIntentRecord)) {
5780            return false;
5781        }
5782        try {
5783            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5784            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5785                return true;
5786            }
5787            return false;
5788        } catch (ClassCastException e) {
5789        }
5790        return false;
5791    }
5792
5793    @Override
5794    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5795        if (!(pendingResult instanceof PendingIntentRecord)) {
5796            return null;
5797        }
5798        try {
5799            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5800            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5801        } catch (ClassCastException e) {
5802        }
5803        return null;
5804    }
5805
5806    @Override
5807    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5808        if (!(pendingResult instanceof PendingIntentRecord)) {
5809            return null;
5810        }
5811        try {
5812            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5813            Intent intent = res.key.requestIntent;
5814            if (intent != null) {
5815                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5816                        || res.lastTagPrefix.equals(prefix))) {
5817                    return res.lastTag;
5818                }
5819                res.lastTagPrefix = prefix;
5820                StringBuilder sb = new StringBuilder(128);
5821                if (prefix != null) {
5822                    sb.append(prefix);
5823                }
5824                if (intent.getAction() != null) {
5825                    sb.append(intent.getAction());
5826                } else if (intent.getComponent() != null) {
5827                    intent.getComponent().appendShortString(sb);
5828                } else {
5829                    sb.append("?");
5830                }
5831                return res.lastTag = sb.toString();
5832            }
5833        } catch (ClassCastException e) {
5834        }
5835        return null;
5836    }
5837
5838    @Override
5839    public void setProcessLimit(int max) {
5840        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5841                "setProcessLimit()");
5842        synchronized (this) {
5843            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5844            mProcessLimitOverride = max;
5845        }
5846        trimApplications();
5847    }
5848
5849    @Override
5850    public int getProcessLimit() {
5851        synchronized (this) {
5852            return mProcessLimitOverride;
5853        }
5854    }
5855
5856    void foregroundTokenDied(ForegroundToken token) {
5857        synchronized (ActivityManagerService.this) {
5858            synchronized (mPidsSelfLocked) {
5859                ForegroundToken cur
5860                    = mForegroundProcesses.get(token.pid);
5861                if (cur != token) {
5862                    return;
5863                }
5864                mForegroundProcesses.remove(token.pid);
5865                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5866                if (pr == null) {
5867                    return;
5868                }
5869                pr.forcingToForeground = null;
5870                updateProcessForegroundLocked(pr, false, false);
5871            }
5872            updateOomAdjLocked();
5873        }
5874    }
5875
5876    @Override
5877    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5878        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5879                "setProcessForeground()");
5880        synchronized(this) {
5881            boolean changed = false;
5882
5883            synchronized (mPidsSelfLocked) {
5884                ProcessRecord pr = mPidsSelfLocked.get(pid);
5885                if (pr == null && isForeground) {
5886                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5887                    return;
5888                }
5889                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5890                if (oldToken != null) {
5891                    oldToken.token.unlinkToDeath(oldToken, 0);
5892                    mForegroundProcesses.remove(pid);
5893                    if (pr != null) {
5894                        pr.forcingToForeground = null;
5895                    }
5896                    changed = true;
5897                }
5898                if (isForeground && token != null) {
5899                    ForegroundToken newToken = new ForegroundToken() {
5900                        @Override
5901                        public void binderDied() {
5902                            foregroundTokenDied(this);
5903                        }
5904                    };
5905                    newToken.pid = pid;
5906                    newToken.token = token;
5907                    try {
5908                        token.linkToDeath(newToken, 0);
5909                        mForegroundProcesses.put(pid, newToken);
5910                        pr.forcingToForeground = token;
5911                        changed = true;
5912                    } catch (RemoteException e) {
5913                        // If the process died while doing this, we will later
5914                        // do the cleanup with the process death link.
5915                    }
5916                }
5917            }
5918
5919            if (changed) {
5920                updateOomAdjLocked();
5921            }
5922        }
5923    }
5924
5925    // =========================================================
5926    // PERMISSIONS
5927    // =========================================================
5928
5929    static class PermissionController extends IPermissionController.Stub {
5930        ActivityManagerService mActivityManagerService;
5931        PermissionController(ActivityManagerService activityManagerService) {
5932            mActivityManagerService = activityManagerService;
5933        }
5934
5935        @Override
5936        public boolean checkPermission(String permission, int pid, int uid) {
5937            return mActivityManagerService.checkPermission(permission, pid,
5938                    uid) == PackageManager.PERMISSION_GRANTED;
5939        }
5940    }
5941
5942    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5943        @Override
5944        public int checkComponentPermission(String permission, int pid, int uid,
5945                int owningUid, boolean exported) {
5946            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5947                    owningUid, exported);
5948        }
5949
5950        @Override
5951        public Object getAMSLock() {
5952            return ActivityManagerService.this;
5953        }
5954    }
5955
5956    /**
5957     * This can be called with or without the global lock held.
5958     */
5959    int checkComponentPermission(String permission, int pid, int uid,
5960            int owningUid, boolean exported) {
5961        // We might be performing an operation on behalf of an indirect binder
5962        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5963        // client identity accordingly before proceeding.
5964        Identity tlsIdentity = sCallerIdentity.get();
5965        if (tlsIdentity != null) {
5966            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5967                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5968            uid = tlsIdentity.uid;
5969            pid = tlsIdentity.pid;
5970        }
5971
5972        if (pid == MY_PID) {
5973            return PackageManager.PERMISSION_GRANTED;
5974        }
5975
5976        return ActivityManager.checkComponentPermission(permission, uid,
5977                owningUid, exported);
5978    }
5979
5980    /**
5981     * As the only public entry point for permissions checking, this method
5982     * can enforce the semantic that requesting a check on a null global
5983     * permission is automatically denied.  (Internally a null permission
5984     * string is used when calling {@link #checkComponentPermission} in cases
5985     * when only uid-based security is needed.)
5986     *
5987     * This can be called with or without the global lock held.
5988     */
5989    @Override
5990    public int checkPermission(String permission, int pid, int uid) {
5991        if (permission == null) {
5992            return PackageManager.PERMISSION_DENIED;
5993        }
5994        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5995    }
5996
5997    /**
5998     * Binder IPC calls go through the public entry point.
5999     * This can be called with or without the global lock held.
6000     */
6001    int checkCallingPermission(String permission) {
6002        return checkPermission(permission,
6003                Binder.getCallingPid(),
6004                UserHandle.getAppId(Binder.getCallingUid()));
6005    }
6006
6007    /**
6008     * This can be called with or without the global lock held.
6009     */
6010    void enforceCallingPermission(String permission, String func) {
6011        if (checkCallingPermission(permission)
6012                == PackageManager.PERMISSION_GRANTED) {
6013            return;
6014        }
6015
6016        String msg = "Permission Denial: " + func + " from pid="
6017                + Binder.getCallingPid()
6018                + ", uid=" + Binder.getCallingUid()
6019                + " requires " + permission;
6020        Slog.w(TAG, msg);
6021        throw new SecurityException(msg);
6022    }
6023
6024    /**
6025     * Determine if UID is holding permissions required to access {@link Uri} in
6026     * the given {@link ProviderInfo}. Final permission checking is always done
6027     * in {@link ContentProvider}.
6028     */
6029    private final boolean checkHoldingPermissionsLocked(
6030            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6031        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6032                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6033        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6034            return false;
6035        }
6036
6037        if (pi.applicationInfo.uid == uid) {
6038            return true;
6039        } else if (!pi.exported) {
6040            return false;
6041        }
6042
6043        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6044        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6045        try {
6046            // check if target holds top-level <provider> permissions
6047            if (!readMet && pi.readPermission != null
6048                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6049                readMet = true;
6050            }
6051            if (!writeMet && pi.writePermission != null
6052                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6053                writeMet = true;
6054            }
6055
6056            // track if unprotected read/write is allowed; any denied
6057            // <path-permission> below removes this ability
6058            boolean allowDefaultRead = pi.readPermission == null;
6059            boolean allowDefaultWrite = pi.writePermission == null;
6060
6061            // check if target holds any <path-permission> that match uri
6062            final PathPermission[] pps = pi.pathPermissions;
6063            if (pps != null) {
6064                final String path = grantUri.uri.getPath();
6065                int i = pps.length;
6066                while (i > 0 && (!readMet || !writeMet)) {
6067                    i--;
6068                    PathPermission pp = pps[i];
6069                    if (pp.match(path)) {
6070                        if (!readMet) {
6071                            final String pprperm = pp.getReadPermission();
6072                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6073                                    + pprperm + " for " + pp.getPath()
6074                                    + ": match=" + pp.match(path)
6075                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6076                            if (pprperm != null) {
6077                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6078                                    readMet = true;
6079                                } else {
6080                                    allowDefaultRead = false;
6081                                }
6082                            }
6083                        }
6084                        if (!writeMet) {
6085                            final String ppwperm = pp.getWritePermission();
6086                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6087                                    + ppwperm + " for " + pp.getPath()
6088                                    + ": match=" + pp.match(path)
6089                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6090                            if (ppwperm != null) {
6091                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6092                                    writeMet = true;
6093                                } else {
6094                                    allowDefaultWrite = false;
6095                                }
6096                            }
6097                        }
6098                    }
6099                }
6100            }
6101
6102            // grant unprotected <provider> read/write, if not blocked by
6103            // <path-permission> above
6104            if (allowDefaultRead) readMet = true;
6105            if (allowDefaultWrite) writeMet = true;
6106
6107        } catch (RemoteException e) {
6108            return false;
6109        }
6110
6111        return readMet && writeMet;
6112    }
6113
6114    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6115        ProviderInfo pi = null;
6116        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6117        if (cpr != null) {
6118            pi = cpr.info;
6119        } else {
6120            try {
6121                pi = AppGlobals.getPackageManager().resolveContentProvider(
6122                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6123            } catch (RemoteException ex) {
6124            }
6125        }
6126        return pi;
6127    }
6128
6129    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6130        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6131        if (targetUris != null) {
6132            return targetUris.get(grantUri);
6133        }
6134        return null;
6135    }
6136
6137    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6138            String targetPkg, int targetUid, GrantUri grantUri) {
6139        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6140        if (targetUris == null) {
6141            targetUris = Maps.newArrayMap();
6142            mGrantedUriPermissions.put(targetUid, targetUris);
6143        }
6144
6145        UriPermission perm = targetUris.get(grantUri);
6146        if (perm == null) {
6147            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6148            targetUris.put(grantUri, perm);
6149        }
6150
6151        return perm;
6152    }
6153
6154    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6155            final int modeFlags) {
6156        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6157        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6158                : UriPermission.STRENGTH_OWNED;
6159
6160        // Root gets to do everything.
6161        if (uid == 0) {
6162            return true;
6163        }
6164
6165        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6166        if (perms == null) return false;
6167
6168        // First look for exact match
6169        final UriPermission exactPerm = perms.get(grantUri);
6170        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6171            return true;
6172        }
6173
6174        // No exact match, look for prefixes
6175        final int N = perms.size();
6176        for (int i = 0; i < N; i++) {
6177            final UriPermission perm = perms.valueAt(i);
6178            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6179                    && perm.getStrength(modeFlags) >= minStrength) {
6180                return true;
6181            }
6182        }
6183
6184        return false;
6185    }
6186
6187    @Override
6188    public int checkUriPermission(Uri uri, int pid, int uid,
6189            final int modeFlags, int userId) {
6190        enforceNotIsolatedCaller("checkUriPermission");
6191
6192        // Another redirected-binder-call permissions check as in
6193        // {@link checkComponentPermission}.
6194        Identity tlsIdentity = sCallerIdentity.get();
6195        if (tlsIdentity != null) {
6196            uid = tlsIdentity.uid;
6197            pid = tlsIdentity.pid;
6198        }
6199
6200        // Our own process gets to do everything.
6201        if (pid == MY_PID) {
6202            return PackageManager.PERMISSION_GRANTED;
6203        }
6204        synchronized (this) {
6205            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6206                    ? PackageManager.PERMISSION_GRANTED
6207                    : PackageManager.PERMISSION_DENIED;
6208        }
6209    }
6210
6211    /**
6212     * Check if the targetPkg can be granted permission to access uri by
6213     * the callingUid using the given modeFlags.  Throws a security exception
6214     * if callingUid is not allowed to do this.  Returns the uid of the target
6215     * if the URI permission grant should be performed; returns -1 if it is not
6216     * needed (for example targetPkg already has permission to access the URI).
6217     * If you already know the uid of the target, you can supply it in
6218     * lastTargetUid else set that to -1.
6219     */
6220    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6221            final int modeFlags, int lastTargetUid) {
6222        if (!Intent.isAccessUriMode(modeFlags)) {
6223            return -1;
6224        }
6225
6226        if (targetPkg != null) {
6227            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6228                    "Checking grant " + targetPkg + " permission to " + grantUri);
6229        }
6230
6231        final IPackageManager pm = AppGlobals.getPackageManager();
6232
6233        // If this is not a content: uri, we can't do anything with it.
6234        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6235            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6236                    "Can't grant URI permission for non-content URI: " + grantUri);
6237            return -1;
6238        }
6239
6240        final String authority = grantUri.uri.getAuthority();
6241        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6242        if (pi == null) {
6243            Slog.w(TAG, "No content provider found for permission check: " +
6244                    grantUri.uri.toSafeString());
6245            return -1;
6246        }
6247
6248        int targetUid = lastTargetUid;
6249        if (targetUid < 0 && targetPkg != null) {
6250            try {
6251                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6252                if (targetUid < 0) {
6253                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6254                            "Can't grant URI permission no uid for: " + targetPkg);
6255                    return -1;
6256                }
6257            } catch (RemoteException ex) {
6258                return -1;
6259            }
6260        }
6261
6262        if (targetUid >= 0) {
6263            // First...  does the target actually need this permission?
6264            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6265                // No need to grant the target this permission.
6266                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6267                        "Target " + targetPkg + " already has full permission to " + grantUri);
6268                return -1;
6269            }
6270        } else {
6271            // First...  there is no target package, so can anyone access it?
6272            boolean allowed = pi.exported;
6273            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6274                if (pi.readPermission != null) {
6275                    allowed = false;
6276                }
6277            }
6278            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6279                if (pi.writePermission != null) {
6280                    allowed = false;
6281                }
6282            }
6283            if (allowed) {
6284                return -1;
6285            }
6286        }
6287
6288        // Second...  is the provider allowing granting of URI permissions?
6289        if (!pi.grantUriPermissions) {
6290            throw new SecurityException("Provider " + pi.packageName
6291                    + "/" + pi.name
6292                    + " does not allow granting of Uri permissions (uri "
6293                    + grantUri + ")");
6294        }
6295        if (pi.uriPermissionPatterns != null) {
6296            final int N = pi.uriPermissionPatterns.length;
6297            boolean allowed = false;
6298            for (int i=0; i<N; i++) {
6299                if (pi.uriPermissionPatterns[i] != null
6300                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6301                    allowed = true;
6302                    break;
6303                }
6304            }
6305            if (!allowed) {
6306                throw new SecurityException("Provider " + pi.packageName
6307                        + "/" + pi.name
6308                        + " does not allow granting of permission to path of Uri "
6309                        + grantUri);
6310            }
6311        }
6312
6313        // Third...  does the caller itself have permission to access
6314        // this uri?
6315        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6316            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6317                // Require they hold a strong enough Uri permission
6318                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6319                    throw new SecurityException("Uid " + callingUid
6320                            + " does not have permission to uri " + grantUri);
6321                }
6322            }
6323        }
6324        return targetUid;
6325    }
6326
6327    @Override
6328    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6329            final int modeFlags, int userId) {
6330        enforceNotIsolatedCaller("checkGrantUriPermission");
6331        synchronized(this) {
6332            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6333                    new GrantUri(userId, uri, false), modeFlags, -1);
6334        }
6335    }
6336
6337    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6338            final int modeFlags, UriPermissionOwner owner) {
6339        if (!Intent.isAccessUriMode(modeFlags)) {
6340            return;
6341        }
6342
6343        // So here we are: the caller has the assumed permission
6344        // to the uri, and the target doesn't.  Let's now give this to
6345        // the target.
6346
6347        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6348                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6349
6350        final String authority = grantUri.uri.getAuthority();
6351        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6352        if (pi == null) {
6353            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6354            return;
6355        }
6356
6357        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6358            grantUri.prefix = true;
6359        }
6360        final UriPermission perm = findOrCreateUriPermissionLocked(
6361                pi.packageName, targetPkg, targetUid, grantUri);
6362        perm.grantModes(modeFlags, owner);
6363    }
6364
6365    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6366            final int modeFlags, UriPermissionOwner owner) {
6367        if (targetPkg == null) {
6368            throw new NullPointerException("targetPkg");
6369        }
6370
6371        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6372                -1);
6373        if (targetUid < 0) {
6374            return;
6375        }
6376
6377        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6378                owner);
6379    }
6380
6381    static class NeededUriGrants extends ArrayList<GrantUri> {
6382        final String targetPkg;
6383        final int targetUid;
6384        final int flags;
6385
6386        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6387            this.targetPkg = targetPkg;
6388            this.targetUid = targetUid;
6389            this.flags = flags;
6390        }
6391    }
6392
6393    /**
6394     * Like checkGrantUriPermissionLocked, but takes an Intent.
6395     */
6396    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6397            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6398        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6399                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6400                + " clip=" + (intent != null ? intent.getClipData() : null)
6401                + " from " + intent + "; flags=0x"
6402                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6403
6404        if (targetPkg == null) {
6405            throw new NullPointerException("targetPkg");
6406        }
6407
6408        if (intent == null) {
6409            return null;
6410        }
6411        Uri data = intent.getData();
6412        ClipData clip = intent.getClipData();
6413        if (data == null && clip == null) {
6414            return null;
6415        }
6416
6417        if (data != null) {
6418            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6419            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6420                    needed != null ? needed.targetUid : -1);
6421            if (targetUid > 0) {
6422                if (needed == null) {
6423                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6424                }
6425                needed.add(grantUri);
6426            }
6427        }
6428        if (clip != null) {
6429            for (int i=0; i<clip.getItemCount(); i++) {
6430                Uri uri = clip.getItemAt(i).getUri();
6431                if (uri != null) {
6432                    int targetUid = -1;
6433                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6434                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6435                            needed != null ? needed.targetUid : -1);
6436                    if (targetUid > 0) {
6437                        if (needed == null) {
6438                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6439                        }
6440                        needed.add(grantUri);
6441                    }
6442                } else {
6443                    Intent clipIntent = clip.getItemAt(i).getIntent();
6444                    if (clipIntent != null) {
6445                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6446                                callingUid, targetPkg, clipIntent, mode, needed);
6447                        if (newNeeded != null) {
6448                            needed = newNeeded;
6449                        }
6450                    }
6451                }
6452            }
6453        }
6454
6455        return needed;
6456    }
6457
6458    /**
6459     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6460     */
6461    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6462            UriPermissionOwner owner) {
6463        if (needed != null) {
6464            for (int i=0; i<needed.size(); i++) {
6465                GrantUri grantUri = needed.get(i);
6466                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6467                        grantUri, needed.flags, owner);
6468            }
6469        }
6470    }
6471
6472    void grantUriPermissionFromIntentLocked(int callingUid,
6473            String targetPkg, Intent intent, UriPermissionOwner owner) {
6474        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6475                intent, intent != null ? intent.getFlags() : 0, null);
6476        if (needed == null) {
6477            return;
6478        }
6479
6480        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6481    }
6482
6483    @Override
6484    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6485            final int modeFlags, int userId) {
6486        enforceNotIsolatedCaller("grantUriPermission");
6487        GrantUri grantUri = new GrantUri(userId, uri, false);
6488        synchronized(this) {
6489            final ProcessRecord r = getRecordForAppLocked(caller);
6490            if (r == null) {
6491                throw new SecurityException("Unable to find app for caller "
6492                        + caller
6493                        + " when granting permission to uri " + grantUri);
6494            }
6495            if (targetPkg == null) {
6496                throw new IllegalArgumentException("null target");
6497            }
6498            if (grantUri == null) {
6499                throw new IllegalArgumentException("null uri");
6500            }
6501
6502            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6503                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6504                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6505                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6506
6507            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6508        }
6509    }
6510
6511    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6512        if (perm.modeFlags == 0) {
6513            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6514                    perm.targetUid);
6515            if (perms != null) {
6516                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6517                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6518
6519                perms.remove(perm.uri);
6520                if (perms.isEmpty()) {
6521                    mGrantedUriPermissions.remove(perm.targetUid);
6522                }
6523            }
6524        }
6525    }
6526
6527    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6528        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6529
6530        final IPackageManager pm = AppGlobals.getPackageManager();
6531        final String authority = grantUri.uri.getAuthority();
6532        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6533        if (pi == null) {
6534            Slog.w(TAG, "No content provider found for permission revoke: "
6535                    + grantUri.toSafeString());
6536            return;
6537        }
6538
6539        // Does the caller have this permission on the URI?
6540        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6541            // Right now, if you are not the original owner of the permission,
6542            // you are not allowed to revoke it.
6543            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6544                throw new SecurityException("Uid " + callingUid
6545                        + " does not have permission to uri " + grantUri);
6546            //}
6547        }
6548
6549        boolean persistChanged = false;
6550
6551        // Go through all of the permissions and remove any that match.
6552        int N = mGrantedUriPermissions.size();
6553        for (int i = 0; i < N; i++) {
6554            final int targetUid = mGrantedUriPermissions.keyAt(i);
6555            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6556
6557            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6558                final UriPermission perm = it.next();
6559                if (perm.uri.sourceUserId == grantUri.sourceUserId
6560                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6561                    if (DEBUG_URI_PERMISSION)
6562                        Slog.v(TAG,
6563                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6564                    persistChanged |= perm.revokeModes(
6565                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6566                    if (perm.modeFlags == 0) {
6567                        it.remove();
6568                    }
6569                }
6570            }
6571
6572            if (perms.isEmpty()) {
6573                mGrantedUriPermissions.remove(targetUid);
6574                N--;
6575                i--;
6576            }
6577        }
6578
6579        if (persistChanged) {
6580            schedulePersistUriGrants();
6581        }
6582    }
6583
6584    @Override
6585    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6586            int userId) {
6587        enforceNotIsolatedCaller("revokeUriPermission");
6588        synchronized(this) {
6589            final ProcessRecord r = getRecordForAppLocked(caller);
6590            if (r == null) {
6591                throw new SecurityException("Unable to find app for caller "
6592                        + caller
6593                        + " when revoking permission to uri " + uri);
6594            }
6595            if (uri == null) {
6596                Slog.w(TAG, "revokeUriPermission: null uri");
6597                return;
6598            }
6599
6600            if (!Intent.isAccessUriMode(modeFlags)) {
6601                return;
6602            }
6603
6604            final IPackageManager pm = AppGlobals.getPackageManager();
6605            final String authority = uri.getAuthority();
6606            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6607            if (pi == null) {
6608                Slog.w(TAG, "No content provider found for permission revoke: "
6609                        + uri.toSafeString());
6610                return;
6611            }
6612
6613            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6614        }
6615    }
6616
6617    /**
6618     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6619     * given package.
6620     *
6621     * @param packageName Package name to match, or {@code null} to apply to all
6622     *            packages.
6623     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6624     *            to all users.
6625     * @param persistable If persistable grants should be removed.
6626     */
6627    private void removeUriPermissionsForPackageLocked(
6628            String packageName, int userHandle, boolean persistable) {
6629        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6630            throw new IllegalArgumentException("Must narrow by either package or user");
6631        }
6632
6633        boolean persistChanged = false;
6634
6635        int N = mGrantedUriPermissions.size();
6636        for (int i = 0; i < N; i++) {
6637            final int targetUid = mGrantedUriPermissions.keyAt(i);
6638            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6639
6640            // Only inspect grants matching user
6641            if (userHandle == UserHandle.USER_ALL
6642                    || userHandle == UserHandle.getUserId(targetUid)) {
6643                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6644                    final UriPermission perm = it.next();
6645
6646                    // Only inspect grants matching package
6647                    if (packageName == null || perm.sourcePkg.equals(packageName)
6648                            || perm.targetPkg.equals(packageName)) {
6649                        persistChanged |= perm.revokeModes(
6650                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6651
6652                        // Only remove when no modes remain; any persisted grants
6653                        // will keep this alive.
6654                        if (perm.modeFlags == 0) {
6655                            it.remove();
6656                        }
6657                    }
6658                }
6659
6660                if (perms.isEmpty()) {
6661                    mGrantedUriPermissions.remove(targetUid);
6662                    N--;
6663                    i--;
6664                }
6665            }
6666        }
6667
6668        if (persistChanged) {
6669            schedulePersistUriGrants();
6670        }
6671    }
6672
6673    @Override
6674    public IBinder newUriPermissionOwner(String name) {
6675        enforceNotIsolatedCaller("newUriPermissionOwner");
6676        synchronized(this) {
6677            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6678            return owner.getExternalTokenLocked();
6679        }
6680    }
6681
6682    @Override
6683    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6684            final int modeFlags, int userId) {
6685        synchronized(this) {
6686            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6687            if (owner == null) {
6688                throw new IllegalArgumentException("Unknown owner: " + token);
6689            }
6690            if (fromUid != Binder.getCallingUid()) {
6691                if (Binder.getCallingUid() != Process.myUid()) {
6692                    // Only system code can grant URI permissions on behalf
6693                    // of other users.
6694                    throw new SecurityException("nice try");
6695                }
6696            }
6697            if (targetPkg == null) {
6698                throw new IllegalArgumentException("null target");
6699            }
6700            if (uri == null) {
6701                throw new IllegalArgumentException("null uri");
6702            }
6703
6704            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6705                    modeFlags, owner);
6706        }
6707    }
6708
6709    @Override
6710    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6711        synchronized(this) {
6712            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6713            if (owner == null) {
6714                throw new IllegalArgumentException("Unknown owner: " + token);
6715            }
6716
6717            if (uri == null) {
6718                owner.removeUriPermissionsLocked(mode);
6719            } else {
6720                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6721            }
6722        }
6723    }
6724
6725    private void schedulePersistUriGrants() {
6726        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6727            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6728                    10 * DateUtils.SECOND_IN_MILLIS);
6729        }
6730    }
6731
6732    private void writeGrantedUriPermissions() {
6733        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6734
6735        // Snapshot permissions so we can persist without lock
6736        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6737        synchronized (this) {
6738            final int size = mGrantedUriPermissions.size();
6739            for (int i = 0; i < size; i++) {
6740                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6741                for (UriPermission perm : perms.values()) {
6742                    if (perm.persistedModeFlags != 0) {
6743                        persist.add(perm.snapshot());
6744                    }
6745                }
6746            }
6747        }
6748
6749        FileOutputStream fos = null;
6750        try {
6751            fos = mGrantFile.startWrite();
6752
6753            XmlSerializer out = new FastXmlSerializer();
6754            out.setOutput(fos, "utf-8");
6755            out.startDocument(null, true);
6756            out.startTag(null, TAG_URI_GRANTS);
6757            for (UriPermission.Snapshot perm : persist) {
6758                out.startTag(null, TAG_URI_GRANT);
6759                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6760                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6761                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6762                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6763                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6764                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6765                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6766                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6767                out.endTag(null, TAG_URI_GRANT);
6768            }
6769            out.endTag(null, TAG_URI_GRANTS);
6770            out.endDocument();
6771
6772            mGrantFile.finishWrite(fos);
6773        } catch (IOException e) {
6774            if (fos != null) {
6775                mGrantFile.failWrite(fos);
6776            }
6777        }
6778    }
6779
6780    private void readGrantedUriPermissionsLocked() {
6781        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6782
6783        final long now = System.currentTimeMillis();
6784
6785        FileInputStream fis = null;
6786        try {
6787            fis = mGrantFile.openRead();
6788            final XmlPullParser in = Xml.newPullParser();
6789            in.setInput(fis, null);
6790
6791            int type;
6792            while ((type = in.next()) != END_DOCUMENT) {
6793                final String tag = in.getName();
6794                if (type == START_TAG) {
6795                    if (TAG_URI_GRANT.equals(tag)) {
6796                        final int sourceUserId;
6797                        final int targetUserId;
6798                        final int userHandle = readIntAttribute(in,
6799                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6800                        if (userHandle != UserHandle.USER_NULL) {
6801                            // For backwards compatibility.
6802                            sourceUserId = userHandle;
6803                            targetUserId = userHandle;
6804                        } else {
6805                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6806                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6807                        }
6808                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6809                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6810                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6811                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6812                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6813                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6814
6815                        // Sanity check that provider still belongs to source package
6816                        final ProviderInfo pi = getProviderInfoLocked(
6817                                uri.getAuthority(), sourceUserId);
6818                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6819                            int targetUid = -1;
6820                            try {
6821                                targetUid = AppGlobals.getPackageManager()
6822                                        .getPackageUid(targetPkg, targetUserId);
6823                            } catch (RemoteException e) {
6824                            }
6825                            if (targetUid != -1) {
6826                                final UriPermission perm = findOrCreateUriPermissionLocked(
6827                                        sourcePkg, targetPkg, targetUid,
6828                                        new GrantUri(sourceUserId, uri, prefix));
6829                                perm.initPersistedModes(modeFlags, createdTime);
6830                            }
6831                        } else {
6832                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6833                                    + " but instead found " + pi);
6834                        }
6835                    }
6836                }
6837            }
6838        } catch (FileNotFoundException e) {
6839            // Missing grants is okay
6840        } catch (IOException e) {
6841            Log.wtf(TAG, "Failed reading Uri grants", e);
6842        } catch (XmlPullParserException e) {
6843            Log.wtf(TAG, "Failed reading Uri grants", e);
6844        } finally {
6845            IoUtils.closeQuietly(fis);
6846        }
6847    }
6848
6849    @Override
6850    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6851        enforceNotIsolatedCaller("takePersistableUriPermission");
6852
6853        Preconditions.checkFlagsArgument(modeFlags,
6854                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6855
6856        synchronized (this) {
6857            final int callingUid = Binder.getCallingUid();
6858            boolean persistChanged = false;
6859            GrantUri grantUri = new GrantUri(userId, uri, false);
6860
6861            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6862                    new GrantUri(userId, uri, false));
6863            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6864                    new GrantUri(userId, uri, true));
6865
6866            final boolean exactValid = (exactPerm != null)
6867                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6868            final boolean prefixValid = (prefixPerm != null)
6869                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6870
6871            if (!(exactValid || prefixValid)) {
6872                throw new SecurityException("No persistable permission grants found for UID "
6873                        + callingUid + " and Uri " + grantUri.toSafeString());
6874            }
6875
6876            if (exactValid) {
6877                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6878            }
6879            if (prefixValid) {
6880                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6881            }
6882
6883            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6884
6885            if (persistChanged) {
6886                schedulePersistUriGrants();
6887            }
6888        }
6889    }
6890
6891    @Override
6892    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6893        enforceNotIsolatedCaller("releasePersistableUriPermission");
6894
6895        Preconditions.checkFlagsArgument(modeFlags,
6896                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6897
6898        synchronized (this) {
6899            final int callingUid = Binder.getCallingUid();
6900            boolean persistChanged = false;
6901
6902            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6903                    new GrantUri(userId, uri, false));
6904            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6905                    new GrantUri(userId, uri, true));
6906            if (exactPerm == null && prefixPerm == null) {
6907                throw new SecurityException("No permission grants found for UID " + callingUid
6908                        + " and Uri " + uri.toSafeString());
6909            }
6910
6911            if (exactPerm != null) {
6912                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6913                removeUriPermissionIfNeededLocked(exactPerm);
6914            }
6915            if (prefixPerm != null) {
6916                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6917                removeUriPermissionIfNeededLocked(prefixPerm);
6918            }
6919
6920            if (persistChanged) {
6921                schedulePersistUriGrants();
6922            }
6923        }
6924    }
6925
6926    /**
6927     * Prune any older {@link UriPermission} for the given UID until outstanding
6928     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6929     *
6930     * @return if any mutations occured that require persisting.
6931     */
6932    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6933        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6934        if (perms == null) return false;
6935        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6936
6937        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6938        for (UriPermission perm : perms.values()) {
6939            if (perm.persistedModeFlags != 0) {
6940                persisted.add(perm);
6941            }
6942        }
6943
6944        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6945        if (trimCount <= 0) return false;
6946
6947        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6948        for (int i = 0; i < trimCount; i++) {
6949            final UriPermission perm = persisted.get(i);
6950
6951            if (DEBUG_URI_PERMISSION) {
6952                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6953            }
6954
6955            perm.releasePersistableModes(~0);
6956            removeUriPermissionIfNeededLocked(perm);
6957        }
6958
6959        return true;
6960    }
6961
6962    @Override
6963    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6964            String packageName, boolean incoming) {
6965        enforceNotIsolatedCaller("getPersistedUriPermissions");
6966        Preconditions.checkNotNull(packageName, "packageName");
6967
6968        final int callingUid = Binder.getCallingUid();
6969        final IPackageManager pm = AppGlobals.getPackageManager();
6970        try {
6971            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6972            if (packageUid != callingUid) {
6973                throw new SecurityException(
6974                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6975            }
6976        } catch (RemoteException e) {
6977            throw new SecurityException("Failed to verify package name ownership");
6978        }
6979
6980        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6981        synchronized (this) {
6982            if (incoming) {
6983                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6984                        callingUid);
6985                if (perms == null) {
6986                    Slog.w(TAG, "No permission grants found for " + packageName);
6987                } else {
6988                    for (UriPermission perm : perms.values()) {
6989                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6990                            result.add(perm.buildPersistedPublicApiObject());
6991                        }
6992                    }
6993                }
6994            } else {
6995                final int size = mGrantedUriPermissions.size();
6996                for (int i = 0; i < size; i++) {
6997                    final ArrayMap<GrantUri, UriPermission> perms =
6998                            mGrantedUriPermissions.valueAt(i);
6999                    for (UriPermission perm : perms.values()) {
7000                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7001                            result.add(perm.buildPersistedPublicApiObject());
7002                        }
7003                    }
7004                }
7005            }
7006        }
7007        return new ParceledListSlice<android.content.UriPermission>(result);
7008    }
7009
7010    @Override
7011    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7012        synchronized (this) {
7013            ProcessRecord app =
7014                who != null ? getRecordForAppLocked(who) : null;
7015            if (app == null) return;
7016
7017            Message msg = Message.obtain();
7018            msg.what = WAIT_FOR_DEBUGGER_MSG;
7019            msg.obj = app;
7020            msg.arg1 = waiting ? 1 : 0;
7021            mHandler.sendMessage(msg);
7022        }
7023    }
7024
7025    @Override
7026    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7027        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7028        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7029        outInfo.availMem = Process.getFreeMemory();
7030        outInfo.totalMem = Process.getTotalMemory();
7031        outInfo.threshold = homeAppMem;
7032        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7033        outInfo.hiddenAppThreshold = cachedAppMem;
7034        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7035                ProcessList.SERVICE_ADJ);
7036        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7037                ProcessList.VISIBLE_APP_ADJ);
7038        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7039                ProcessList.FOREGROUND_APP_ADJ);
7040    }
7041
7042    // =========================================================
7043    // TASK MANAGEMENT
7044    // =========================================================
7045
7046    @Override
7047    public List<IAppTask> getAppTasks() {
7048        int callingUid = Binder.getCallingUid();
7049        long ident = Binder.clearCallingIdentity();
7050        synchronized(this) {
7051            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7052            try {
7053                if (localLOGV) Slog.v(TAG, "getAppTasks");
7054
7055                final int N = mRecentTasks.size();
7056                for (int i = 0; i < N; i++) {
7057                    TaskRecord tr = mRecentTasks.get(i);
7058                    // Skip tasks that are not created by the caller
7059                    if (tr.creatorUid == callingUid) {
7060                        ActivityManager.RecentTaskInfo taskInfo =
7061                                createRecentTaskInfoFromTaskRecord(tr);
7062                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7063                        list.add(taskImpl);
7064                    }
7065                }
7066            } finally {
7067                Binder.restoreCallingIdentity(ident);
7068            }
7069            return list;
7070        }
7071    }
7072
7073    @Override
7074    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7075        final int callingUid = Binder.getCallingUid();
7076        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7077
7078        synchronized(this) {
7079            if (localLOGV) Slog.v(
7080                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7081
7082            final boolean allowed = checkCallingPermission(
7083                    android.Manifest.permission.GET_TASKS)
7084                    == PackageManager.PERMISSION_GRANTED;
7085            if (!allowed) {
7086                Slog.w(TAG, "getTasks: caller " + callingUid
7087                        + " does not hold GET_TASKS; limiting output");
7088            }
7089
7090            // TODO: Improve with MRU list from all ActivityStacks.
7091            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7092        }
7093
7094        return list;
7095    }
7096
7097    TaskRecord getMostRecentTask() {
7098        return mRecentTasks.get(0);
7099    }
7100
7101    /**
7102     * Creates a new RecentTaskInfo from a TaskRecord.
7103     */
7104    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7105        // Update the task description to reflect any changes in the task stack
7106        tr.updateTaskDescription();
7107
7108        // Compose the recent task info
7109        ActivityManager.RecentTaskInfo rti
7110                = new ActivityManager.RecentTaskInfo();
7111        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7112        rti.persistentId = tr.taskId;
7113        rti.baseIntent = new Intent(tr.getBaseIntent());
7114        rti.origActivity = tr.origActivity;
7115        rti.description = tr.lastDescription;
7116        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7117        rti.userId = tr.userId;
7118        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7119        return rti;
7120    }
7121
7122    @Override
7123    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7124            int flags, int userId) {
7125        final int callingUid = Binder.getCallingUid();
7126        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7127                false, true, "getRecentTasks", null);
7128
7129        synchronized (this) {
7130            final boolean allowed = checkCallingPermission(
7131                    android.Manifest.permission.GET_TASKS)
7132                    == PackageManager.PERMISSION_GRANTED;
7133            if (!allowed) {
7134                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7135                        + " does not hold GET_TASKS; limiting output");
7136            }
7137            final boolean detailed = checkCallingPermission(
7138                    android.Manifest.permission.GET_DETAILED_TASKS)
7139                    == PackageManager.PERMISSION_GRANTED;
7140
7141            IPackageManager pm = AppGlobals.getPackageManager();
7142
7143            final int N = mRecentTasks.size();
7144            ArrayList<ActivityManager.RecentTaskInfo> res
7145                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7146                            maxNum < N ? maxNum : N);
7147
7148            final Set<Integer> includedUsers;
7149            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7150                includedUsers = getProfileIdsLocked(userId);
7151            } else {
7152                includedUsers = new HashSet<Integer>();
7153            }
7154            includedUsers.add(Integer.valueOf(userId));
7155            for (int i=0; i<N && maxNum > 0; i++) {
7156                TaskRecord tr = mRecentTasks.get(i);
7157                // Only add calling user or related users recent tasks
7158                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7159
7160                // Return the entry if desired by the caller.  We always return
7161                // the first entry, because callers always expect this to be the
7162                // foreground app.  We may filter others if the caller has
7163                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7164                // we should exclude the entry.
7165
7166                if (i == 0
7167                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7168                        || (tr.intent == null)
7169                        || ((tr.intent.getFlags()
7170                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7171                    if (!allowed) {
7172                        // If the caller doesn't have the GET_TASKS permission, then only
7173                        // allow them to see a small subset of tasks -- their own and home.
7174                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7175                            continue;
7176                        }
7177                    }
7178
7179                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7180                    if (!detailed) {
7181                        rti.baseIntent.replaceExtras((Bundle)null);
7182                    }
7183
7184                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7185                        // Check whether this activity is currently available.
7186                        try {
7187                            if (rti.origActivity != null) {
7188                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7189                                        == null) {
7190                                    continue;
7191                                }
7192                            } else if (rti.baseIntent != null) {
7193                                if (pm.queryIntentActivities(rti.baseIntent,
7194                                        null, 0, userId) == null) {
7195                                    continue;
7196                                }
7197                            }
7198                        } catch (RemoteException e) {
7199                            // Will never happen.
7200                        }
7201                    }
7202
7203                    res.add(rti);
7204                    maxNum--;
7205                }
7206            }
7207            return res;
7208        }
7209    }
7210
7211    private TaskRecord recentTaskForIdLocked(int id) {
7212        final int N = mRecentTasks.size();
7213            for (int i=0; i<N; i++) {
7214                TaskRecord tr = mRecentTasks.get(i);
7215                if (tr.taskId == id) {
7216                    return tr;
7217                }
7218            }
7219            return null;
7220    }
7221
7222    @Override
7223    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7224        synchronized (this) {
7225            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7226                    "getTaskThumbnails()");
7227            TaskRecord tr = recentTaskForIdLocked(id);
7228            if (tr != null) {
7229                return tr.getTaskThumbnailsLocked();
7230            }
7231        }
7232        return null;
7233    }
7234
7235    @Override
7236    public Bitmap getTaskTopThumbnail(int id) {
7237        synchronized (this) {
7238            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7239                    "getTaskTopThumbnail()");
7240            TaskRecord tr = recentTaskForIdLocked(id);
7241            if (tr != null) {
7242                return tr.getTaskTopThumbnailLocked();
7243            }
7244        }
7245        return null;
7246    }
7247
7248    @Override
7249    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7250        synchronized (this) {
7251            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7252            if (r != null) {
7253                r.taskDescription = td;
7254                r.task.updateTaskDescription();
7255            }
7256        }
7257    }
7258
7259    @Override
7260    public boolean removeSubTask(int taskId, int subTaskIndex) {
7261        synchronized (this) {
7262            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7263                    "removeSubTask()");
7264            long ident = Binder.clearCallingIdentity();
7265            try {
7266                TaskRecord tr = recentTaskForIdLocked(taskId);
7267                if (tr != null) {
7268                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7269                }
7270                return false;
7271            } finally {
7272                Binder.restoreCallingIdentity(ident);
7273            }
7274        }
7275    }
7276
7277    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7278        if (!pr.killedByAm) {
7279            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7280            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7281                    pr.processName, pr.setAdj, reason);
7282            pr.killedByAm = true;
7283            Process.killProcessQuiet(pr.pid);
7284        }
7285    }
7286
7287    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7288        tr.disposeThumbnail();
7289        mRecentTasks.remove(tr);
7290        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7291        Intent baseIntent = new Intent(
7292                tr.intent != null ? tr.intent : tr.affinityIntent);
7293        ComponentName component = baseIntent.getComponent();
7294        if (component == null) {
7295            Slog.w(TAG, "Now component for base intent of task: " + tr);
7296            return;
7297        }
7298
7299        // Find any running services associated with this app.
7300        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7301
7302        if (killProcesses) {
7303            // Find any running processes associated with this app.
7304            final String pkg = component.getPackageName();
7305            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7306            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7307            for (int i=0; i<pmap.size(); i++) {
7308                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7309                for (int j=0; j<uids.size(); j++) {
7310                    ProcessRecord proc = uids.valueAt(j);
7311                    if (proc.userId != tr.userId) {
7312                        continue;
7313                    }
7314                    if (!proc.pkgList.containsKey(pkg)) {
7315                        continue;
7316                    }
7317                    procs.add(proc);
7318                }
7319            }
7320
7321            // Kill the running processes.
7322            for (int i=0; i<procs.size(); i++) {
7323                ProcessRecord pr = procs.get(i);
7324                if (pr == mHomeProcess) {
7325                    // Don't kill the home process along with tasks from the same package.
7326                    continue;
7327                }
7328                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7329                    killUnneededProcessLocked(pr, "remove task");
7330                } else {
7331                    pr.waitingToKill = "remove task";
7332                }
7333            }
7334        }
7335    }
7336
7337    /**
7338     * Removes the task with the specified task id.
7339     *
7340     * @param taskId Identifier of the task to be removed.
7341     * @param flags Additional operational flags.  May be 0 or
7342     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7343     * @return Returns true if the given task was found and removed.
7344     */
7345    private boolean removeTaskByIdLocked(int taskId, int flags) {
7346        TaskRecord tr = recentTaskForIdLocked(taskId);
7347        if (tr != null) {
7348            tr.removeTaskActivitiesLocked(-1, false);
7349            cleanUpRemovedTaskLocked(tr, flags);
7350            if (tr.isPersistable) {
7351                notifyTaskPersisterLocked(tr, true);
7352            }
7353            return true;
7354        }
7355        return false;
7356    }
7357
7358    @Override
7359    public boolean removeTask(int taskId, int flags) {
7360        synchronized (this) {
7361            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7362                    "removeTask()");
7363            long ident = Binder.clearCallingIdentity();
7364            try {
7365                return removeTaskByIdLocked(taskId, flags);
7366            } finally {
7367                Binder.restoreCallingIdentity(ident);
7368            }
7369        }
7370    }
7371
7372    /**
7373     * TODO: Add mController hook
7374     */
7375    @Override
7376    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7377        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7378                "moveTaskToFront()");
7379
7380        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7381        synchronized(this) {
7382            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7383                    Binder.getCallingUid(), "Task to front")) {
7384                ActivityOptions.abort(options);
7385                return;
7386            }
7387            final long origId = Binder.clearCallingIdentity();
7388            try {
7389                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7390                if (task == null) {
7391                    return;
7392                }
7393                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7394                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7395                    return;
7396                }
7397                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7398            } finally {
7399                Binder.restoreCallingIdentity(origId);
7400            }
7401            ActivityOptions.abort(options);
7402        }
7403    }
7404
7405    @Override
7406    public void moveTaskToBack(int taskId) {
7407        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7408                "moveTaskToBack()");
7409
7410        synchronized(this) {
7411            TaskRecord tr = recentTaskForIdLocked(taskId);
7412            if (tr != null) {
7413                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7414                ActivityStack stack = tr.stack;
7415                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7416                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7417                            Binder.getCallingUid(), "Task to back")) {
7418                        return;
7419                    }
7420                }
7421                final long origId = Binder.clearCallingIdentity();
7422                try {
7423                    stack.moveTaskToBackLocked(taskId, null);
7424                } finally {
7425                    Binder.restoreCallingIdentity(origId);
7426                }
7427            }
7428        }
7429    }
7430
7431    /**
7432     * Moves an activity, and all of the other activities within the same task, to the bottom
7433     * of the history stack.  The activity's order within the task is unchanged.
7434     *
7435     * @param token A reference to the activity we wish to move
7436     * @param nonRoot If false then this only works if the activity is the root
7437     *                of a task; if true it will work for any activity in a task.
7438     * @return Returns true if the move completed, false if not.
7439     */
7440    @Override
7441    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7442        enforceNotIsolatedCaller("moveActivityTaskToBack");
7443        synchronized(this) {
7444            final long origId = Binder.clearCallingIdentity();
7445            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7446            if (taskId >= 0) {
7447                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7448            }
7449            Binder.restoreCallingIdentity(origId);
7450        }
7451        return false;
7452    }
7453
7454    @Override
7455    public void moveTaskBackwards(int task) {
7456        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7457                "moveTaskBackwards()");
7458
7459        synchronized(this) {
7460            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7461                    Binder.getCallingUid(), "Task backwards")) {
7462                return;
7463            }
7464            final long origId = Binder.clearCallingIdentity();
7465            moveTaskBackwardsLocked(task);
7466            Binder.restoreCallingIdentity(origId);
7467        }
7468    }
7469
7470    private final void moveTaskBackwardsLocked(int task) {
7471        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7472    }
7473
7474    @Override
7475    public IBinder getHomeActivityToken() throws RemoteException {
7476        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7477                "getHomeActivityToken()");
7478        synchronized (this) {
7479            return mStackSupervisor.getHomeActivityToken();
7480        }
7481    }
7482
7483    @Override
7484    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7485            IActivityContainerCallback callback) throws RemoteException {
7486        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7487                "createActivityContainer()");
7488        synchronized (this) {
7489            if (parentActivityToken == null) {
7490                throw new IllegalArgumentException("parent token must not be null");
7491            }
7492            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7493            if (r == null) {
7494                return null;
7495            }
7496            if (callback == null) {
7497                throw new IllegalArgumentException("callback must not be null");
7498            }
7499            return mStackSupervisor.createActivityContainer(r, callback);
7500        }
7501    }
7502
7503    @Override
7504    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7505        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7506                "deleteActivityContainer()");
7507        synchronized (this) {
7508            mStackSupervisor.deleteActivityContainer(container);
7509        }
7510    }
7511
7512    @Override
7513    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7514            throws RemoteException {
7515        synchronized (this) {
7516            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7517            if (stack != null) {
7518                return stack.mActivityContainer;
7519            }
7520            return null;
7521        }
7522    }
7523
7524    @Override
7525    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7526        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7527                "moveTaskToStack()");
7528        if (stackId == HOME_STACK_ID) {
7529            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7530                    new RuntimeException("here").fillInStackTrace());
7531        }
7532        synchronized (this) {
7533            long ident = Binder.clearCallingIdentity();
7534            try {
7535                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7536                        + stackId + " toTop=" + toTop);
7537                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7538            } finally {
7539                Binder.restoreCallingIdentity(ident);
7540            }
7541        }
7542    }
7543
7544    @Override
7545    public void resizeStack(int stackBoxId, Rect bounds) {
7546        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7547                "resizeStackBox()");
7548        long ident = Binder.clearCallingIdentity();
7549        try {
7550            mWindowManager.resizeStack(stackBoxId, bounds);
7551        } finally {
7552            Binder.restoreCallingIdentity(ident);
7553        }
7554    }
7555
7556    @Override
7557    public List<StackInfo> getAllStackInfos() {
7558        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7559                "getAllStackInfos()");
7560        long ident = Binder.clearCallingIdentity();
7561        try {
7562            synchronized (this) {
7563                return mStackSupervisor.getAllStackInfosLocked();
7564            }
7565        } finally {
7566            Binder.restoreCallingIdentity(ident);
7567        }
7568    }
7569
7570    @Override
7571    public StackInfo getStackInfo(int stackId) {
7572        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7573                "getStackInfo()");
7574        long ident = Binder.clearCallingIdentity();
7575        try {
7576            synchronized (this) {
7577                return mStackSupervisor.getStackInfoLocked(stackId);
7578            }
7579        } finally {
7580            Binder.restoreCallingIdentity(ident);
7581        }
7582    }
7583
7584    @Override
7585    public boolean isInHomeStack(int taskId) {
7586        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7587                "getStackInfo()");
7588        long ident = Binder.clearCallingIdentity();
7589        try {
7590            synchronized (this) {
7591                TaskRecord tr = recentTaskForIdLocked(taskId);
7592                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7593            }
7594        } finally {
7595            Binder.restoreCallingIdentity(ident);
7596        }
7597    }
7598
7599    @Override
7600    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7601        synchronized(this) {
7602            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7603        }
7604    }
7605
7606    private boolean isLockTaskAuthorized(ComponentName name) {
7607        final DevicePolicyManager dpm = (DevicePolicyManager)
7608                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7609        return dpm != null && dpm.isLockTaskPermitted(name);
7610    }
7611
7612    private void startLockTaskMode(TaskRecord task) {
7613        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7614            return;
7615        }
7616        long ident = Binder.clearCallingIdentity();
7617        try {
7618            synchronized (this) {
7619                // Since we lost lock on task, make sure it is still there.
7620                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7621                if (task != null) {
7622                    mStackSupervisor.setLockTaskModeLocked(task);
7623                }
7624            }
7625        } finally {
7626            Binder.restoreCallingIdentity(ident);
7627        }
7628    }
7629
7630    @Override
7631    public void startLockTaskMode(int taskId) {
7632        long ident = Binder.clearCallingIdentity();
7633        try {
7634            final TaskRecord task;
7635            synchronized (this) {
7636                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7637            }
7638            if (task != null) {
7639                startLockTaskMode(task);
7640            }
7641        } finally {
7642            Binder.restoreCallingIdentity(ident);
7643        }
7644    }
7645
7646    @Override
7647    public void startLockTaskMode(IBinder token) {
7648        long ident = Binder.clearCallingIdentity();
7649        try {
7650            final TaskRecord task;
7651            synchronized (this) {
7652                final ActivityRecord r = ActivityRecord.forToken(token);
7653                if (r == null) {
7654                    return;
7655                }
7656                task = r.task;
7657            }
7658            if (task != null) {
7659                startLockTaskMode(task);
7660            }
7661        } finally {
7662            Binder.restoreCallingIdentity(ident);
7663        }
7664    }
7665
7666    @Override
7667    public void stopLockTaskMode() {
7668        // Check if the calling task is eligible to use lock task
7669        final int uid = Binder.getCallingUid();
7670        try {
7671            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7672            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7673                return;
7674            }
7675        } catch (RemoteException e) {
7676            Log.d(TAG, "stopLockTaskMode " + e);
7677            return;
7678        }
7679        // Stop lock task
7680        synchronized (this) {
7681            mStackSupervisor.setLockTaskModeLocked(null);
7682        }
7683    }
7684
7685    @Override
7686    public boolean isInLockTaskMode() {
7687        synchronized (this) {
7688            return mStackSupervisor.isInLockTaskMode();
7689        }
7690    }
7691
7692    // =========================================================
7693    // CONTENT PROVIDERS
7694    // =========================================================
7695
7696    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7697        List<ProviderInfo> providers = null;
7698        try {
7699            providers = AppGlobals.getPackageManager().
7700                queryContentProviders(app.processName, app.uid,
7701                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7702        } catch (RemoteException ex) {
7703        }
7704        if (DEBUG_MU)
7705            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7706        int userId = app.userId;
7707        if (providers != null) {
7708            int N = providers.size();
7709            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7710            for (int i=0; i<N; i++) {
7711                ProviderInfo cpi =
7712                    (ProviderInfo)providers.get(i);
7713                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7714                        cpi.name, cpi.flags);
7715                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7716                    // This is a singleton provider, but a user besides the
7717                    // default user is asking to initialize a process it runs
7718                    // in...  well, no, it doesn't actually run in this process,
7719                    // it runs in the process of the default user.  Get rid of it.
7720                    providers.remove(i);
7721                    N--;
7722                    i--;
7723                    continue;
7724                }
7725
7726                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7727                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7728                if (cpr == null) {
7729                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7730                    mProviderMap.putProviderByClass(comp, cpr);
7731                }
7732                if (DEBUG_MU)
7733                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7734                app.pubProviders.put(cpi.name, cpr);
7735                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7736                    // Don't add this if it is a platform component that is marked
7737                    // to run in multiple processes, because this is actually
7738                    // part of the framework so doesn't make sense to track as a
7739                    // separate apk in the process.
7740                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7741                }
7742                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7743            }
7744        }
7745        return providers;
7746    }
7747
7748    /**
7749     * Check if {@link ProcessRecord} has a possible chance at accessing the
7750     * given {@link ProviderInfo}. Final permission checking is always done
7751     * in {@link ContentProvider}.
7752     */
7753    private final String checkContentProviderPermissionLocked(
7754            ProviderInfo cpi, ProcessRecord r, int userId) {
7755        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7756        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7757        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7758        // Looking for cross-user grants before to enforce the typical cross-users permissions
7759        if (userId != UserHandle.getUserId(callingUid)) {
7760            if (perms != null) {
7761                for (GrantUri grantUri : perms.keySet()) {
7762                    if (grantUri.sourceUserId == userId) {
7763                        String authority = grantUri.uri.getAuthority();
7764                        if (authority.equals(cpi.authority)) {
7765                            return null;
7766                        }
7767                    }
7768                }
7769            }
7770        }
7771        userId = handleIncomingUser(callingPid, callingUid, userId,
7772                false, true, "checkContentProviderPermissionLocked", null);
7773        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7774                cpi.applicationInfo.uid, cpi.exported)
7775                == PackageManager.PERMISSION_GRANTED) {
7776            return null;
7777        }
7778        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7779                cpi.applicationInfo.uid, cpi.exported)
7780                == PackageManager.PERMISSION_GRANTED) {
7781            return null;
7782        }
7783
7784        PathPermission[] pps = cpi.pathPermissions;
7785        if (pps != null) {
7786            int i = pps.length;
7787            while (i > 0) {
7788                i--;
7789                PathPermission pp = pps[i];
7790                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7791                        cpi.applicationInfo.uid, cpi.exported)
7792                        == PackageManager.PERMISSION_GRANTED) {
7793                    return null;
7794                }
7795                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7796                        cpi.applicationInfo.uid, cpi.exported)
7797                        == PackageManager.PERMISSION_GRANTED) {
7798                    return null;
7799                }
7800            }
7801        }
7802
7803        if (perms != null) {
7804            for (GrantUri grantUri : perms.keySet()) {
7805                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7806                    return null;
7807                }
7808            }
7809        }
7810
7811        String msg;
7812        if (!cpi.exported) {
7813            msg = "Permission Denial: opening provider " + cpi.name
7814                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7815                    + ", uid=" + callingUid + ") that is not exported from uid "
7816                    + cpi.applicationInfo.uid;
7817        } else {
7818            msg = "Permission Denial: opening provider " + cpi.name
7819                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7820                    + ", uid=" + callingUid + ") requires "
7821                    + cpi.readPermission + " or " + cpi.writePermission;
7822        }
7823        Slog.w(TAG, msg);
7824        return msg;
7825    }
7826
7827    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7828            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7829        if (r != null) {
7830            for (int i=0; i<r.conProviders.size(); i++) {
7831                ContentProviderConnection conn = r.conProviders.get(i);
7832                if (conn.provider == cpr) {
7833                    if (DEBUG_PROVIDER) Slog.v(TAG,
7834                            "Adding provider requested by "
7835                            + r.processName + " from process "
7836                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7837                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7838                    if (stable) {
7839                        conn.stableCount++;
7840                        conn.numStableIncs++;
7841                    } else {
7842                        conn.unstableCount++;
7843                        conn.numUnstableIncs++;
7844                    }
7845                    return conn;
7846                }
7847            }
7848            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7849            if (stable) {
7850                conn.stableCount = 1;
7851                conn.numStableIncs = 1;
7852            } else {
7853                conn.unstableCount = 1;
7854                conn.numUnstableIncs = 1;
7855            }
7856            cpr.connections.add(conn);
7857            r.conProviders.add(conn);
7858            return conn;
7859        }
7860        cpr.addExternalProcessHandleLocked(externalProcessToken);
7861        return null;
7862    }
7863
7864    boolean decProviderCountLocked(ContentProviderConnection conn,
7865            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7866        if (conn != null) {
7867            cpr = conn.provider;
7868            if (DEBUG_PROVIDER) Slog.v(TAG,
7869                    "Removing provider requested by "
7870                    + conn.client.processName + " from process "
7871                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7872                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7873            if (stable) {
7874                conn.stableCount--;
7875            } else {
7876                conn.unstableCount--;
7877            }
7878            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7879                cpr.connections.remove(conn);
7880                conn.client.conProviders.remove(conn);
7881                return true;
7882            }
7883            return false;
7884        }
7885        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7886        return false;
7887    }
7888
7889    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7890            String name, IBinder token, boolean stable, int userId) {
7891        ContentProviderRecord cpr;
7892        ContentProviderConnection conn = null;
7893        ProviderInfo cpi = null;
7894
7895        synchronized(this) {
7896            ProcessRecord r = null;
7897            if (caller != null) {
7898                r = getRecordForAppLocked(caller);
7899                if (r == null) {
7900                    throw new SecurityException(
7901                            "Unable to find app for caller " + caller
7902                          + " (pid=" + Binder.getCallingPid()
7903                          + ") when getting content provider " + name);
7904                }
7905            }
7906
7907            // First check if this content provider has been published...
7908            cpr = mProviderMap.getProviderByName(name, userId);
7909            boolean providerRunning = cpr != null;
7910            if (providerRunning) {
7911                cpi = cpr.info;
7912                String msg;
7913                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7914                    throw new SecurityException(msg);
7915                }
7916
7917                if (r != null && cpr.canRunHere(r)) {
7918                    // This provider has been published or is in the process
7919                    // of being published...  but it is also allowed to run
7920                    // in the caller's process, so don't make a connection
7921                    // and just let the caller instantiate its own instance.
7922                    ContentProviderHolder holder = cpr.newHolder(null);
7923                    // don't give caller the provider object, it needs
7924                    // to make its own.
7925                    holder.provider = null;
7926                    return holder;
7927                }
7928
7929                final long origId = Binder.clearCallingIdentity();
7930
7931                // In this case the provider instance already exists, so we can
7932                // return it right away.
7933                conn = incProviderCountLocked(r, cpr, token, stable);
7934                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7935                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7936                        // If this is a perceptible app accessing the provider,
7937                        // make sure to count it as being accessed and thus
7938                        // back up on the LRU list.  This is good because
7939                        // content providers are often expensive to start.
7940                        updateLruProcessLocked(cpr.proc, false, null);
7941                    }
7942                }
7943
7944                if (cpr.proc != null) {
7945                    if (false) {
7946                        if (cpr.name.flattenToShortString().equals(
7947                                "com.android.providers.calendar/.CalendarProvider2")) {
7948                            Slog.v(TAG, "****************** KILLING "
7949                                + cpr.name.flattenToShortString());
7950                            Process.killProcess(cpr.proc.pid);
7951                        }
7952                    }
7953                    boolean success = updateOomAdjLocked(cpr.proc);
7954                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7955                    // NOTE: there is still a race here where a signal could be
7956                    // pending on the process even though we managed to update its
7957                    // adj level.  Not sure what to do about this, but at least
7958                    // the race is now smaller.
7959                    if (!success) {
7960                        // Uh oh...  it looks like the provider's process
7961                        // has been killed on us.  We need to wait for a new
7962                        // process to be started, and make sure its death
7963                        // doesn't kill our process.
7964                        Slog.i(TAG,
7965                                "Existing provider " + cpr.name.flattenToShortString()
7966                                + " is crashing; detaching " + r);
7967                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7968                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7969                        if (!lastRef) {
7970                            // This wasn't the last ref our process had on
7971                            // the provider...  we have now been killed, bail.
7972                            return null;
7973                        }
7974                        providerRunning = false;
7975                        conn = null;
7976                    }
7977                }
7978
7979                Binder.restoreCallingIdentity(origId);
7980            }
7981
7982            boolean singleton;
7983            if (!providerRunning) {
7984                try {
7985                    cpi = AppGlobals.getPackageManager().
7986                        resolveContentProvider(name,
7987                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7988                } catch (RemoteException ex) {
7989                }
7990                if (cpi == null) {
7991                    return null;
7992                }
7993                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7994                        cpi.name, cpi.flags);
7995                if (singleton) {
7996                    userId = 0;
7997                }
7998                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7999
8000                String msg;
8001                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
8002                    throw new SecurityException(msg);
8003                }
8004
8005                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8006                        && !cpi.processName.equals("system")) {
8007                    // If this content provider does not run in the system
8008                    // process, and the system is not yet ready to run other
8009                    // processes, then fail fast instead of hanging.
8010                    throw new IllegalArgumentException(
8011                            "Attempt to launch content provider before system ready");
8012                }
8013
8014                // Make sure that the user who owns this provider is started.  If not,
8015                // we don't want to allow it to run.
8016                if (mStartedUsers.get(userId) == null) {
8017                    Slog.w(TAG, "Unable to launch app "
8018                            + cpi.applicationInfo.packageName + "/"
8019                            + cpi.applicationInfo.uid + " for provider "
8020                            + name + ": user " + userId + " is stopped");
8021                    return null;
8022                }
8023
8024                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8025                cpr = mProviderMap.getProviderByClass(comp, userId);
8026                final boolean firstClass = cpr == null;
8027                if (firstClass) {
8028                    try {
8029                        ApplicationInfo ai =
8030                            AppGlobals.getPackageManager().
8031                                getApplicationInfo(
8032                                        cpi.applicationInfo.packageName,
8033                                        STOCK_PM_FLAGS, userId);
8034                        if (ai == null) {
8035                            Slog.w(TAG, "No package info for content provider "
8036                                    + cpi.name);
8037                            return null;
8038                        }
8039                        ai = getAppInfoForUser(ai, userId);
8040                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8041                    } catch (RemoteException ex) {
8042                        // pm is in same process, this will never happen.
8043                    }
8044                }
8045
8046                if (r != null && cpr.canRunHere(r)) {
8047                    // If this is a multiprocess provider, then just return its
8048                    // info and allow the caller to instantiate it.  Only do
8049                    // this if the provider is the same user as the caller's
8050                    // process, or can run as root (so can be in any process).
8051                    return cpr.newHolder(null);
8052                }
8053
8054                if (DEBUG_PROVIDER) {
8055                    RuntimeException e = new RuntimeException("here");
8056                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8057                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8058                }
8059
8060                // This is single process, and our app is now connecting to it.
8061                // See if we are already in the process of launching this
8062                // provider.
8063                final int N = mLaunchingProviders.size();
8064                int i;
8065                for (i=0; i<N; i++) {
8066                    if (mLaunchingProviders.get(i) == cpr) {
8067                        break;
8068                    }
8069                }
8070
8071                // If the provider is not already being launched, then get it
8072                // started.
8073                if (i >= N) {
8074                    final long origId = Binder.clearCallingIdentity();
8075
8076                    try {
8077                        // Content provider is now in use, its package can't be stopped.
8078                        try {
8079                            AppGlobals.getPackageManager().setPackageStoppedState(
8080                                    cpr.appInfo.packageName, false, userId);
8081                        } catch (RemoteException e) {
8082                        } catch (IllegalArgumentException e) {
8083                            Slog.w(TAG, "Failed trying to unstop package "
8084                                    + cpr.appInfo.packageName + ": " + e);
8085                        }
8086
8087                        // Use existing process if already started
8088                        ProcessRecord proc = getProcessRecordLocked(
8089                                cpi.processName, cpr.appInfo.uid, false);
8090                        if (proc != null && proc.thread != null) {
8091                            if (DEBUG_PROVIDER) {
8092                                Slog.d(TAG, "Installing in existing process " + proc);
8093                            }
8094                            proc.pubProviders.put(cpi.name, cpr);
8095                            try {
8096                                proc.thread.scheduleInstallProvider(cpi);
8097                            } catch (RemoteException e) {
8098                            }
8099                        } else {
8100                            proc = startProcessLocked(cpi.processName,
8101                                    cpr.appInfo, false, 0, "content provider",
8102                                    new ComponentName(cpi.applicationInfo.packageName,
8103                                            cpi.name), false, false, false);
8104                            if (proc == null) {
8105                                Slog.w(TAG, "Unable to launch app "
8106                                        + cpi.applicationInfo.packageName + "/"
8107                                        + cpi.applicationInfo.uid + " for provider "
8108                                        + name + ": process is bad");
8109                                return null;
8110                            }
8111                        }
8112                        cpr.launchingApp = proc;
8113                        mLaunchingProviders.add(cpr);
8114                    } finally {
8115                        Binder.restoreCallingIdentity(origId);
8116                    }
8117                }
8118
8119                // Make sure the provider is published (the same provider class
8120                // may be published under multiple names).
8121                if (firstClass) {
8122                    mProviderMap.putProviderByClass(comp, cpr);
8123                }
8124
8125                mProviderMap.putProviderByName(name, cpr);
8126                conn = incProviderCountLocked(r, cpr, token, stable);
8127                if (conn != null) {
8128                    conn.waiting = true;
8129                }
8130            }
8131        }
8132
8133        // Wait for the provider to be published...
8134        synchronized (cpr) {
8135            while (cpr.provider == null) {
8136                if (cpr.launchingApp == null) {
8137                    Slog.w(TAG, "Unable to launch app "
8138                            + cpi.applicationInfo.packageName + "/"
8139                            + cpi.applicationInfo.uid + " for provider "
8140                            + name + ": launching app became null");
8141                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8142                            UserHandle.getUserId(cpi.applicationInfo.uid),
8143                            cpi.applicationInfo.packageName,
8144                            cpi.applicationInfo.uid, name);
8145                    return null;
8146                }
8147                try {
8148                    if (DEBUG_MU) {
8149                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8150                                + cpr.launchingApp);
8151                    }
8152                    if (conn != null) {
8153                        conn.waiting = true;
8154                    }
8155                    cpr.wait();
8156                } catch (InterruptedException ex) {
8157                } finally {
8158                    if (conn != null) {
8159                        conn.waiting = false;
8160                    }
8161                }
8162            }
8163        }
8164        return cpr != null ? cpr.newHolder(conn) : null;
8165    }
8166
8167    @Override
8168    public final ContentProviderHolder getContentProvider(
8169            IApplicationThread caller, String name, int userId, boolean stable) {
8170        enforceNotIsolatedCaller("getContentProvider");
8171        if (caller == null) {
8172            String msg = "null IApplicationThread when getting content provider "
8173                    + name;
8174            Slog.w(TAG, msg);
8175            throw new SecurityException(msg);
8176        }
8177        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8178        // with cross-user grant.
8179        return getContentProviderImpl(caller, name, null, stable, userId);
8180    }
8181
8182    public ContentProviderHolder getContentProviderExternal(
8183            String name, int userId, IBinder token) {
8184        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8185            "Do not have permission in call getContentProviderExternal()");
8186        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8187                false, true, "getContentProvider", null);
8188        return getContentProviderExternalUnchecked(name, token, userId);
8189    }
8190
8191    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8192            IBinder token, int userId) {
8193        return getContentProviderImpl(null, name, token, true, userId);
8194    }
8195
8196    /**
8197     * Drop a content provider from a ProcessRecord's bookkeeping
8198     */
8199    public void removeContentProvider(IBinder connection, boolean stable) {
8200        enforceNotIsolatedCaller("removeContentProvider");
8201        long ident = Binder.clearCallingIdentity();
8202        try {
8203            synchronized (this) {
8204                ContentProviderConnection conn;
8205                try {
8206                    conn = (ContentProviderConnection)connection;
8207                } catch (ClassCastException e) {
8208                    String msg ="removeContentProvider: " + connection
8209                            + " not a ContentProviderConnection";
8210                    Slog.w(TAG, msg);
8211                    throw new IllegalArgumentException(msg);
8212                }
8213                if (conn == null) {
8214                    throw new NullPointerException("connection is null");
8215                }
8216                if (decProviderCountLocked(conn, null, null, stable)) {
8217                    updateOomAdjLocked();
8218                }
8219            }
8220        } finally {
8221            Binder.restoreCallingIdentity(ident);
8222        }
8223    }
8224
8225    public void removeContentProviderExternal(String name, IBinder token) {
8226        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8227            "Do not have permission in call removeContentProviderExternal()");
8228        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8229    }
8230
8231    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8232        synchronized (this) {
8233            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8234            if(cpr == null) {
8235                //remove from mProvidersByClass
8236                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8237                return;
8238            }
8239
8240            //update content provider record entry info
8241            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8242            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8243            if (localCpr.hasExternalProcessHandles()) {
8244                if (localCpr.removeExternalProcessHandleLocked(token)) {
8245                    updateOomAdjLocked();
8246                } else {
8247                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8248                            + " with no external reference for token: "
8249                            + token + ".");
8250                }
8251            } else {
8252                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8253                        + " with no external references.");
8254            }
8255        }
8256    }
8257
8258    public final void publishContentProviders(IApplicationThread caller,
8259            List<ContentProviderHolder> providers) {
8260        if (providers == null) {
8261            return;
8262        }
8263
8264        enforceNotIsolatedCaller("publishContentProviders");
8265        synchronized (this) {
8266            final ProcessRecord r = getRecordForAppLocked(caller);
8267            if (DEBUG_MU)
8268                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8269            if (r == null) {
8270                throw new SecurityException(
8271                        "Unable to find app for caller " + caller
8272                      + " (pid=" + Binder.getCallingPid()
8273                      + ") when publishing content providers");
8274            }
8275
8276            final long origId = Binder.clearCallingIdentity();
8277
8278            final int N = providers.size();
8279            for (int i=0; i<N; i++) {
8280                ContentProviderHolder src = providers.get(i);
8281                if (src == null || src.info == null || src.provider == null) {
8282                    continue;
8283                }
8284                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8285                if (DEBUG_MU)
8286                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8287                if (dst != null) {
8288                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8289                    mProviderMap.putProviderByClass(comp, dst);
8290                    String names[] = dst.info.authority.split(";");
8291                    for (int j = 0; j < names.length; j++) {
8292                        mProviderMap.putProviderByName(names[j], dst);
8293                    }
8294
8295                    int NL = mLaunchingProviders.size();
8296                    int j;
8297                    for (j=0; j<NL; j++) {
8298                        if (mLaunchingProviders.get(j) == dst) {
8299                            mLaunchingProviders.remove(j);
8300                            j--;
8301                            NL--;
8302                        }
8303                    }
8304                    synchronized (dst) {
8305                        dst.provider = src.provider;
8306                        dst.proc = r;
8307                        dst.notifyAll();
8308                    }
8309                    updateOomAdjLocked(r);
8310                }
8311            }
8312
8313            Binder.restoreCallingIdentity(origId);
8314        }
8315    }
8316
8317    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8318        ContentProviderConnection conn;
8319        try {
8320            conn = (ContentProviderConnection)connection;
8321        } catch (ClassCastException e) {
8322            String msg ="refContentProvider: " + connection
8323                    + " not a ContentProviderConnection";
8324            Slog.w(TAG, msg);
8325            throw new IllegalArgumentException(msg);
8326        }
8327        if (conn == null) {
8328            throw new NullPointerException("connection is null");
8329        }
8330
8331        synchronized (this) {
8332            if (stable > 0) {
8333                conn.numStableIncs += stable;
8334            }
8335            stable = conn.stableCount + stable;
8336            if (stable < 0) {
8337                throw new IllegalStateException("stableCount < 0: " + stable);
8338            }
8339
8340            if (unstable > 0) {
8341                conn.numUnstableIncs += unstable;
8342            }
8343            unstable = conn.unstableCount + unstable;
8344            if (unstable < 0) {
8345                throw new IllegalStateException("unstableCount < 0: " + unstable);
8346            }
8347
8348            if ((stable+unstable) <= 0) {
8349                throw new IllegalStateException("ref counts can't go to zero here: stable="
8350                        + stable + " unstable=" + unstable);
8351            }
8352            conn.stableCount = stable;
8353            conn.unstableCount = unstable;
8354            return !conn.dead;
8355        }
8356    }
8357
8358    public void unstableProviderDied(IBinder connection) {
8359        ContentProviderConnection conn;
8360        try {
8361            conn = (ContentProviderConnection)connection;
8362        } catch (ClassCastException e) {
8363            String msg ="refContentProvider: " + connection
8364                    + " not a ContentProviderConnection";
8365            Slog.w(TAG, msg);
8366            throw new IllegalArgumentException(msg);
8367        }
8368        if (conn == null) {
8369            throw new NullPointerException("connection is null");
8370        }
8371
8372        // Safely retrieve the content provider associated with the connection.
8373        IContentProvider provider;
8374        synchronized (this) {
8375            provider = conn.provider.provider;
8376        }
8377
8378        if (provider == null) {
8379            // Um, yeah, we're way ahead of you.
8380            return;
8381        }
8382
8383        // Make sure the caller is being honest with us.
8384        if (provider.asBinder().pingBinder()) {
8385            // Er, no, still looks good to us.
8386            synchronized (this) {
8387                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8388                        + " says " + conn + " died, but we don't agree");
8389                return;
8390            }
8391        }
8392
8393        // Well look at that!  It's dead!
8394        synchronized (this) {
8395            if (conn.provider.provider != provider) {
8396                // But something changed...  good enough.
8397                return;
8398            }
8399
8400            ProcessRecord proc = conn.provider.proc;
8401            if (proc == null || proc.thread == null) {
8402                // Seems like the process is already cleaned up.
8403                return;
8404            }
8405
8406            // As far as we're concerned, this is just like receiving a
8407            // death notification...  just a bit prematurely.
8408            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8409                    + ") early provider death");
8410            final long ident = Binder.clearCallingIdentity();
8411            try {
8412                appDiedLocked(proc, proc.pid, proc.thread);
8413            } finally {
8414                Binder.restoreCallingIdentity(ident);
8415            }
8416        }
8417    }
8418
8419    @Override
8420    public void appNotRespondingViaProvider(IBinder connection) {
8421        enforceCallingPermission(
8422                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8423
8424        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8425        if (conn == null) {
8426            Slog.w(TAG, "ContentProviderConnection is null");
8427            return;
8428        }
8429
8430        final ProcessRecord host = conn.provider.proc;
8431        if (host == null) {
8432            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8433            return;
8434        }
8435
8436        final long token = Binder.clearCallingIdentity();
8437        try {
8438            appNotResponding(host, null, null, false, "ContentProvider not responding");
8439        } finally {
8440            Binder.restoreCallingIdentity(token);
8441        }
8442    }
8443
8444    public final void installSystemProviders() {
8445        List<ProviderInfo> providers;
8446        synchronized (this) {
8447            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8448            providers = generateApplicationProvidersLocked(app);
8449            if (providers != null) {
8450                for (int i=providers.size()-1; i>=0; i--) {
8451                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8452                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8453                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8454                                + ": not system .apk");
8455                        providers.remove(i);
8456                    }
8457                }
8458            }
8459        }
8460        if (providers != null) {
8461            mSystemThread.installSystemProviders(providers);
8462        }
8463
8464        mCoreSettingsObserver = new CoreSettingsObserver(this);
8465
8466        mUsageStatsService.monitorPackages();
8467    }
8468
8469    /**
8470     * Allows app to retrieve the MIME type of a URI without having permission
8471     * to access its content provider.
8472     *
8473     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8474     *
8475     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8476     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8477     */
8478    public String getProviderMimeType(Uri uri, int userId) {
8479        enforceNotIsolatedCaller("getProviderMimeType");
8480        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8481                userId, false, true, "getProviderMimeType", null);
8482        final String name = uri.getAuthority();
8483        final long ident = Binder.clearCallingIdentity();
8484        ContentProviderHolder holder = null;
8485
8486        try {
8487            holder = getContentProviderExternalUnchecked(name, null, userId);
8488            if (holder != null) {
8489                return holder.provider.getType(uri);
8490            }
8491        } catch (RemoteException e) {
8492            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8493            return null;
8494        } finally {
8495            if (holder != null) {
8496                removeContentProviderExternalUnchecked(name, null, userId);
8497            }
8498            Binder.restoreCallingIdentity(ident);
8499        }
8500
8501        return null;
8502    }
8503
8504    // =========================================================
8505    // GLOBAL MANAGEMENT
8506    // =========================================================
8507
8508    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8509            boolean isolated) {
8510        String proc = customProcess != null ? customProcess : info.processName;
8511        BatteryStatsImpl.Uid.Proc ps = null;
8512        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8513        int uid = info.uid;
8514        if (isolated) {
8515            int userId = UserHandle.getUserId(uid);
8516            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8517            while (true) {
8518                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8519                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8520                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8521                }
8522                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8523                mNextIsolatedProcessUid++;
8524                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8525                    // No process for this uid, use it.
8526                    break;
8527                }
8528                stepsLeft--;
8529                if (stepsLeft <= 0) {
8530                    return null;
8531                }
8532            }
8533        }
8534        return new ProcessRecord(stats, info, proc, uid);
8535    }
8536
8537    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8538        ProcessRecord app;
8539        if (!isolated) {
8540            app = getProcessRecordLocked(info.processName, info.uid, true);
8541        } else {
8542            app = null;
8543        }
8544
8545        if (app == null) {
8546            app = newProcessRecordLocked(info, null, isolated);
8547            mProcessNames.put(info.processName, app.uid, app);
8548            if (isolated) {
8549                mIsolatedProcesses.put(app.uid, app);
8550            }
8551            updateLruProcessLocked(app, false, null);
8552            updateOomAdjLocked();
8553        }
8554
8555        // This package really, really can not be stopped.
8556        try {
8557            AppGlobals.getPackageManager().setPackageStoppedState(
8558                    info.packageName, false, UserHandle.getUserId(app.uid));
8559        } catch (RemoteException e) {
8560        } catch (IllegalArgumentException e) {
8561            Slog.w(TAG, "Failed trying to unstop package "
8562                    + info.packageName + ": " + e);
8563        }
8564
8565        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8566                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8567            app.persistent = true;
8568            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8569        }
8570        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8571            mPersistentStartingProcesses.add(app);
8572            startProcessLocked(app, "added application", app.processName);
8573        }
8574
8575        return app;
8576    }
8577
8578    public void unhandledBack() {
8579        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8580                "unhandledBack()");
8581
8582        synchronized(this) {
8583            final long origId = Binder.clearCallingIdentity();
8584            try {
8585                getFocusedStack().unhandledBackLocked();
8586            } finally {
8587                Binder.restoreCallingIdentity(origId);
8588            }
8589        }
8590    }
8591
8592    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8593        enforceNotIsolatedCaller("openContentUri");
8594        final int userId = UserHandle.getCallingUserId();
8595        String name = uri.getAuthority();
8596        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8597        ParcelFileDescriptor pfd = null;
8598        if (cph != null) {
8599            // We record the binder invoker's uid in thread-local storage before
8600            // going to the content provider to open the file.  Later, in the code
8601            // that handles all permissions checks, we look for this uid and use
8602            // that rather than the Activity Manager's own uid.  The effect is that
8603            // we do the check against the caller's permissions even though it looks
8604            // to the content provider like the Activity Manager itself is making
8605            // the request.
8606            sCallerIdentity.set(new Identity(
8607                    Binder.getCallingPid(), Binder.getCallingUid()));
8608            try {
8609                pfd = cph.provider.openFile(null, uri, "r", null);
8610            } catch (FileNotFoundException e) {
8611                // do nothing; pfd will be returned null
8612            } finally {
8613                // Ensure that whatever happens, we clean up the identity state
8614                sCallerIdentity.remove();
8615            }
8616
8617            // We've got the fd now, so we're done with the provider.
8618            removeContentProviderExternalUnchecked(name, null, userId);
8619        } else {
8620            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8621        }
8622        return pfd;
8623    }
8624
8625    // Actually is sleeping or shutting down or whatever else in the future
8626    // is an inactive state.
8627    public boolean isSleepingOrShuttingDown() {
8628        return mSleeping || mShuttingDown;
8629    }
8630
8631    public boolean isSleeping() {
8632        return mSleeping;
8633    }
8634
8635    void goingToSleep() {
8636        synchronized(this) {
8637            mWentToSleep = true;
8638            updateEventDispatchingLocked();
8639            goToSleepIfNeededLocked();
8640        }
8641    }
8642
8643    void finishRunningVoiceLocked() {
8644        if (mRunningVoice) {
8645            mRunningVoice = false;
8646            goToSleepIfNeededLocked();
8647        }
8648    }
8649
8650    void goToSleepIfNeededLocked() {
8651        if (mWentToSleep && !mRunningVoice) {
8652            if (!mSleeping) {
8653                mSleeping = true;
8654                mStackSupervisor.goingToSleepLocked();
8655
8656                // Initialize the wake times of all processes.
8657                checkExcessivePowerUsageLocked(false);
8658                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8659                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8660                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8661            }
8662        }
8663    }
8664
8665    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8666        mTaskPersister.notify(task, flush);
8667    }
8668
8669    @Override
8670    public boolean shutdown(int timeout) {
8671        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8672                != PackageManager.PERMISSION_GRANTED) {
8673            throw new SecurityException("Requires permission "
8674                    + android.Manifest.permission.SHUTDOWN);
8675        }
8676
8677        boolean timedout = false;
8678
8679        synchronized(this) {
8680            mShuttingDown = true;
8681            updateEventDispatchingLocked();
8682            timedout = mStackSupervisor.shutdownLocked(timeout);
8683        }
8684
8685        mAppOpsService.shutdown();
8686        mUsageStatsService.shutdown();
8687        mBatteryStatsService.shutdown();
8688        synchronized (this) {
8689            mProcessStats.shutdownLocked();
8690        }
8691        notifyTaskPersisterLocked(null, true);
8692
8693        return timedout;
8694    }
8695
8696    public final void activitySlept(IBinder token) {
8697        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8698
8699        final long origId = Binder.clearCallingIdentity();
8700
8701        synchronized (this) {
8702            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8703            if (r != null) {
8704                mStackSupervisor.activitySleptLocked(r);
8705            }
8706        }
8707
8708        Binder.restoreCallingIdentity(origId);
8709    }
8710
8711    void logLockScreen(String msg) {
8712        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8713                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8714                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8715                mStackSupervisor.mDismissKeyguardOnNextActivity);
8716    }
8717
8718    private void comeOutOfSleepIfNeededLocked() {
8719        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8720            if (mSleeping) {
8721                mSleeping = false;
8722                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8723            }
8724        }
8725    }
8726
8727    void wakingUp() {
8728        synchronized(this) {
8729            mWentToSleep = false;
8730            updateEventDispatchingLocked();
8731            comeOutOfSleepIfNeededLocked();
8732        }
8733    }
8734
8735    void startRunningVoiceLocked() {
8736        if (!mRunningVoice) {
8737            mRunningVoice = true;
8738            comeOutOfSleepIfNeededLocked();
8739        }
8740    }
8741
8742    private void updateEventDispatchingLocked() {
8743        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8744    }
8745
8746    public void setLockScreenShown(boolean shown) {
8747        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8748                != PackageManager.PERMISSION_GRANTED) {
8749            throw new SecurityException("Requires permission "
8750                    + android.Manifest.permission.DEVICE_POWER);
8751        }
8752
8753        synchronized(this) {
8754            long ident = Binder.clearCallingIdentity();
8755            try {
8756                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8757                mLockScreenShown = shown;
8758                comeOutOfSleepIfNeededLocked();
8759            } finally {
8760                Binder.restoreCallingIdentity(ident);
8761            }
8762        }
8763    }
8764
8765    public void stopAppSwitches() {
8766        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8767                != PackageManager.PERMISSION_GRANTED) {
8768            throw new SecurityException("Requires permission "
8769                    + android.Manifest.permission.STOP_APP_SWITCHES);
8770        }
8771
8772        synchronized(this) {
8773            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8774                    + APP_SWITCH_DELAY_TIME;
8775            mDidAppSwitch = false;
8776            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8777            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8778            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8779        }
8780    }
8781
8782    public void resumeAppSwitches() {
8783        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8784                != PackageManager.PERMISSION_GRANTED) {
8785            throw new SecurityException("Requires permission "
8786                    + android.Manifest.permission.STOP_APP_SWITCHES);
8787        }
8788
8789        synchronized(this) {
8790            // Note that we don't execute any pending app switches... we will
8791            // let those wait until either the timeout, or the next start
8792            // activity request.
8793            mAppSwitchesAllowedTime = 0;
8794        }
8795    }
8796
8797    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8798            String name) {
8799        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8800            return true;
8801        }
8802
8803        final int perm = checkComponentPermission(
8804                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8805                callingUid, -1, true);
8806        if (perm == PackageManager.PERMISSION_GRANTED) {
8807            return true;
8808        }
8809
8810        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8811        return false;
8812    }
8813
8814    public void setDebugApp(String packageName, boolean waitForDebugger,
8815            boolean persistent) {
8816        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8817                "setDebugApp()");
8818
8819        long ident = Binder.clearCallingIdentity();
8820        try {
8821            // Note that this is not really thread safe if there are multiple
8822            // callers into it at the same time, but that's not a situation we
8823            // care about.
8824            if (persistent) {
8825                final ContentResolver resolver = mContext.getContentResolver();
8826                Settings.Global.putString(
8827                    resolver, Settings.Global.DEBUG_APP,
8828                    packageName);
8829                Settings.Global.putInt(
8830                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8831                    waitForDebugger ? 1 : 0);
8832            }
8833
8834            synchronized (this) {
8835                if (!persistent) {
8836                    mOrigDebugApp = mDebugApp;
8837                    mOrigWaitForDebugger = mWaitForDebugger;
8838                }
8839                mDebugApp = packageName;
8840                mWaitForDebugger = waitForDebugger;
8841                mDebugTransient = !persistent;
8842                if (packageName != null) {
8843                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8844                            false, UserHandle.USER_ALL, "set debug app");
8845                }
8846            }
8847        } finally {
8848            Binder.restoreCallingIdentity(ident);
8849        }
8850    }
8851
8852    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8853        synchronized (this) {
8854            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8855            if (!isDebuggable) {
8856                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8857                    throw new SecurityException("Process not debuggable: " + app.packageName);
8858                }
8859            }
8860
8861            mOpenGlTraceApp = processName;
8862        }
8863    }
8864
8865    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8866            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8867        synchronized (this) {
8868            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8869            if (!isDebuggable) {
8870                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8871                    throw new SecurityException("Process not debuggable: " + app.packageName);
8872                }
8873            }
8874            mProfileApp = processName;
8875            mProfileFile = profileFile;
8876            if (mProfileFd != null) {
8877                try {
8878                    mProfileFd.close();
8879                } catch (IOException e) {
8880                }
8881                mProfileFd = null;
8882            }
8883            mProfileFd = profileFd;
8884            mProfileType = 0;
8885            mAutoStopProfiler = autoStopProfiler;
8886        }
8887    }
8888
8889    @Override
8890    public void setAlwaysFinish(boolean enabled) {
8891        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8892                "setAlwaysFinish()");
8893
8894        Settings.Global.putInt(
8895                mContext.getContentResolver(),
8896                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8897
8898        synchronized (this) {
8899            mAlwaysFinishActivities = enabled;
8900        }
8901    }
8902
8903    @Override
8904    public void setActivityController(IActivityController controller) {
8905        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8906                "setActivityController()");
8907        synchronized (this) {
8908            mController = controller;
8909            Watchdog.getInstance().setActivityController(controller);
8910        }
8911    }
8912
8913    @Override
8914    public void setUserIsMonkey(boolean userIsMonkey) {
8915        synchronized (this) {
8916            synchronized (mPidsSelfLocked) {
8917                final int callingPid = Binder.getCallingPid();
8918                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8919                if (precessRecord == null) {
8920                    throw new SecurityException("Unknown process: " + callingPid);
8921                }
8922                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8923                    throw new SecurityException("Only an instrumentation process "
8924                            + "with a UiAutomation can call setUserIsMonkey");
8925                }
8926            }
8927            mUserIsMonkey = userIsMonkey;
8928        }
8929    }
8930
8931    @Override
8932    public boolean isUserAMonkey() {
8933        synchronized (this) {
8934            // If there is a controller also implies the user is a monkey.
8935            return (mUserIsMonkey || mController != null);
8936        }
8937    }
8938
8939    public void requestBugReport() {
8940        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8941        SystemProperties.set("ctl.start", "bugreport");
8942    }
8943
8944    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8945        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8946    }
8947
8948    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8949        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8950            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8951        }
8952        return KEY_DISPATCHING_TIMEOUT;
8953    }
8954
8955    @Override
8956    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8957        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8958                != PackageManager.PERMISSION_GRANTED) {
8959            throw new SecurityException("Requires permission "
8960                    + android.Manifest.permission.FILTER_EVENTS);
8961        }
8962        ProcessRecord proc;
8963        long timeout;
8964        synchronized (this) {
8965            synchronized (mPidsSelfLocked) {
8966                proc = mPidsSelfLocked.get(pid);
8967            }
8968            timeout = getInputDispatchingTimeoutLocked(proc);
8969        }
8970
8971        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8972            return -1;
8973        }
8974
8975        return timeout;
8976    }
8977
8978    /**
8979     * Handle input dispatching timeouts.
8980     * Returns whether input dispatching should be aborted or not.
8981     */
8982    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8983            final ActivityRecord activity, final ActivityRecord parent,
8984            final boolean aboveSystem, String reason) {
8985        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8986                != PackageManager.PERMISSION_GRANTED) {
8987            throw new SecurityException("Requires permission "
8988                    + android.Manifest.permission.FILTER_EVENTS);
8989        }
8990
8991        final String annotation;
8992        if (reason == null) {
8993            annotation = "Input dispatching timed out";
8994        } else {
8995            annotation = "Input dispatching timed out (" + reason + ")";
8996        }
8997
8998        if (proc != null) {
8999            synchronized (this) {
9000                if (proc.debugging) {
9001                    return false;
9002                }
9003
9004                if (mDidDexOpt) {
9005                    // Give more time since we were dexopting.
9006                    mDidDexOpt = false;
9007                    return false;
9008                }
9009
9010                if (proc.instrumentationClass != null) {
9011                    Bundle info = new Bundle();
9012                    info.putString("shortMsg", "keyDispatchingTimedOut");
9013                    info.putString("longMsg", annotation);
9014                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9015                    return true;
9016                }
9017            }
9018            mHandler.post(new Runnable() {
9019                @Override
9020                public void run() {
9021                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9022                }
9023            });
9024        }
9025
9026        return true;
9027    }
9028
9029    public Bundle getAssistContextExtras(int requestType) {
9030        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9031                "getAssistContextExtras()");
9032        PendingAssistExtras pae;
9033        Bundle extras = new Bundle();
9034        synchronized (this) {
9035            ActivityRecord activity = getFocusedStack().mResumedActivity;
9036            if (activity == null) {
9037                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9038                return null;
9039            }
9040            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9041            if (activity.app == null || activity.app.thread == null) {
9042                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9043                return extras;
9044            }
9045            if (activity.app.pid == Binder.getCallingPid()) {
9046                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9047                return extras;
9048            }
9049            pae = new PendingAssistExtras(activity);
9050            try {
9051                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9052                        requestType);
9053                mPendingAssistExtras.add(pae);
9054                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9055            } catch (RemoteException e) {
9056                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9057                return extras;
9058            }
9059        }
9060        synchronized (pae) {
9061            while (!pae.haveResult) {
9062                try {
9063                    pae.wait();
9064                } catch (InterruptedException e) {
9065                }
9066            }
9067            if (pae.result != null) {
9068                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9069            }
9070        }
9071        synchronized (this) {
9072            mPendingAssistExtras.remove(pae);
9073            mHandler.removeCallbacks(pae);
9074        }
9075        return extras;
9076    }
9077
9078    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9079        PendingAssistExtras pae = (PendingAssistExtras)token;
9080        synchronized (pae) {
9081            pae.result = extras;
9082            pae.haveResult = true;
9083            pae.notifyAll();
9084        }
9085    }
9086
9087    public void registerProcessObserver(IProcessObserver observer) {
9088        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9089                "registerProcessObserver()");
9090        synchronized (this) {
9091            mProcessObservers.register(observer);
9092        }
9093    }
9094
9095    @Override
9096    public void unregisterProcessObserver(IProcessObserver observer) {
9097        synchronized (this) {
9098            mProcessObservers.unregister(observer);
9099        }
9100    }
9101
9102    @Override
9103    public boolean convertFromTranslucent(IBinder token) {
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(true)) {
9112                    mWindowManager.setAppFullscreen(token, true);
9113                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9114                    return true;
9115                }
9116                return false;
9117            }
9118        } finally {
9119            Binder.restoreCallingIdentity(origId);
9120        }
9121    }
9122
9123    @Override
9124    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9125        final long origId = Binder.clearCallingIdentity();
9126        try {
9127            synchronized (this) {
9128                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9129                if (r == null) {
9130                    return false;
9131                }
9132                if (r.changeWindowTranslucency(false)) {
9133                    r.task.stack.convertToTranslucent(r, options);
9134                    mWindowManager.setAppFullscreen(token, false);
9135                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9136                    return true;
9137                }
9138                return false;
9139            }
9140        } finally {
9141            Binder.restoreCallingIdentity(origId);
9142        }
9143    }
9144
9145    @Override
9146    public ActivityOptions getActivityOptions(IBinder token) {
9147        final long origId = Binder.clearCallingIdentity();
9148        try {
9149            synchronized (this) {
9150                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9151                if (r != null) {
9152                    final ActivityOptions activityOptions = r.pendingOptions;
9153                    r.pendingOptions = null;
9154                    return activityOptions;
9155                }
9156                return null;
9157            }
9158        } finally {
9159            Binder.restoreCallingIdentity(origId);
9160        }
9161    }
9162
9163    @Override
9164    public void setImmersive(IBinder token, boolean immersive) {
9165        synchronized(this) {
9166            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9167            if (r == null) {
9168                throw new IllegalArgumentException();
9169            }
9170            r.immersive = immersive;
9171
9172            // update associated state if we're frontmost
9173            if (r == mFocusedActivity) {
9174                if (DEBUG_IMMERSIVE) {
9175                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9176                }
9177                applyUpdateLockStateLocked(r);
9178            }
9179        }
9180    }
9181
9182    @Override
9183    public boolean isImmersive(IBinder token) {
9184        synchronized (this) {
9185            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9186            if (r == null) {
9187                throw new IllegalArgumentException();
9188            }
9189            return r.immersive;
9190        }
9191    }
9192
9193    public boolean isTopActivityImmersive() {
9194        enforceNotIsolatedCaller("startActivity");
9195        synchronized (this) {
9196            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9197            return (r != null) ? r.immersive : false;
9198        }
9199    }
9200
9201    public final void enterSafeMode() {
9202        synchronized(this) {
9203            // It only makes sense to do this before the system is ready
9204            // and started launching other packages.
9205            if (!mSystemReady) {
9206                try {
9207                    AppGlobals.getPackageManager().enterSafeMode();
9208                } catch (RemoteException e) {
9209                }
9210            }
9211
9212            mSafeMode = true;
9213        }
9214    }
9215
9216    public final void showSafeModeOverlay() {
9217        View v = LayoutInflater.from(mContext).inflate(
9218                com.android.internal.R.layout.safe_mode, null);
9219        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9220        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9221        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9222        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9223        lp.gravity = Gravity.BOTTOM | Gravity.START;
9224        lp.format = v.getBackground().getOpacity();
9225        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9226                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9227        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9228        ((WindowManager)mContext.getSystemService(
9229                Context.WINDOW_SERVICE)).addView(v, lp);
9230    }
9231
9232    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9233        if (!(sender instanceof PendingIntentRecord)) {
9234            return;
9235        }
9236        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9237        synchronized (stats) {
9238            if (mBatteryStatsService.isOnBattery()) {
9239                mBatteryStatsService.enforceCallingPermission();
9240                PendingIntentRecord rec = (PendingIntentRecord)sender;
9241                int MY_UID = Binder.getCallingUid();
9242                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9243                BatteryStatsImpl.Uid.Pkg pkg =
9244                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9245                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9246                pkg.incWakeupsLocked();
9247            }
9248        }
9249    }
9250
9251    public boolean killPids(int[] pids, String pReason, boolean secure) {
9252        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9253            throw new SecurityException("killPids only available to the system");
9254        }
9255        String reason = (pReason == null) ? "Unknown" : pReason;
9256        // XXX Note: don't acquire main activity lock here, because the window
9257        // manager calls in with its locks held.
9258
9259        boolean killed = false;
9260        synchronized (mPidsSelfLocked) {
9261            int[] types = new int[pids.length];
9262            int worstType = 0;
9263            for (int i=0; i<pids.length; i++) {
9264                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9265                if (proc != null) {
9266                    int type = proc.setAdj;
9267                    types[i] = type;
9268                    if (type > worstType) {
9269                        worstType = type;
9270                    }
9271                }
9272            }
9273
9274            // If the worst oom_adj is somewhere in the cached proc LRU range,
9275            // then constrain it so we will kill all cached procs.
9276            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9277                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9278                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9279            }
9280
9281            // If this is not a secure call, don't let it kill processes that
9282            // are important.
9283            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9284                worstType = ProcessList.SERVICE_ADJ;
9285            }
9286
9287            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9288            for (int i=0; i<pids.length; i++) {
9289                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9290                if (proc == null) {
9291                    continue;
9292                }
9293                int adj = proc.setAdj;
9294                if (adj >= worstType && !proc.killedByAm) {
9295                    killUnneededProcessLocked(proc, reason);
9296                    killed = true;
9297                }
9298            }
9299        }
9300        return killed;
9301    }
9302
9303    @Override
9304    public void killUid(int uid, String reason) {
9305        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9306            throw new SecurityException("killUid only available to the system");
9307        }
9308        synchronized (this) {
9309            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9310                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9311                    reason != null ? reason : "kill uid");
9312        }
9313    }
9314
9315    @Override
9316    public boolean killProcessesBelowForeground(String reason) {
9317        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9318            throw new SecurityException("killProcessesBelowForeground() only available to system");
9319        }
9320
9321        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9322    }
9323
9324    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9325        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9326            throw new SecurityException("killProcessesBelowAdj() only available to system");
9327        }
9328
9329        boolean killed = false;
9330        synchronized (mPidsSelfLocked) {
9331            final int size = mPidsSelfLocked.size();
9332            for (int i = 0; i < size; i++) {
9333                final int pid = mPidsSelfLocked.keyAt(i);
9334                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9335                if (proc == null) continue;
9336
9337                final int adj = proc.setAdj;
9338                if (adj > belowAdj && !proc.killedByAm) {
9339                    killUnneededProcessLocked(proc, reason);
9340                    killed = true;
9341                }
9342            }
9343        }
9344        return killed;
9345    }
9346
9347    @Override
9348    public void hang(final IBinder who, boolean allowRestart) {
9349        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9350                != PackageManager.PERMISSION_GRANTED) {
9351            throw new SecurityException("Requires permission "
9352                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9353        }
9354
9355        final IBinder.DeathRecipient death = new DeathRecipient() {
9356            @Override
9357            public void binderDied() {
9358                synchronized (this) {
9359                    notifyAll();
9360                }
9361            }
9362        };
9363
9364        try {
9365            who.linkToDeath(death, 0);
9366        } catch (RemoteException e) {
9367            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9368            return;
9369        }
9370
9371        synchronized (this) {
9372            Watchdog.getInstance().setAllowRestart(allowRestart);
9373            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9374            synchronized (death) {
9375                while (who.isBinderAlive()) {
9376                    try {
9377                        death.wait();
9378                    } catch (InterruptedException e) {
9379                    }
9380                }
9381            }
9382            Watchdog.getInstance().setAllowRestart(true);
9383        }
9384    }
9385
9386    @Override
9387    public void restart() {
9388        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9389                != PackageManager.PERMISSION_GRANTED) {
9390            throw new SecurityException("Requires permission "
9391                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9392        }
9393
9394        Log.i(TAG, "Sending shutdown broadcast...");
9395
9396        BroadcastReceiver br = new BroadcastReceiver() {
9397            @Override public void onReceive(Context context, Intent intent) {
9398                // Now the broadcast is done, finish up the low-level shutdown.
9399                Log.i(TAG, "Shutting down activity manager...");
9400                shutdown(10000);
9401                Log.i(TAG, "Shutdown complete, restarting!");
9402                Process.killProcess(Process.myPid());
9403                System.exit(10);
9404            }
9405        };
9406
9407        // First send the high-level shut down broadcast.
9408        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9409        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9410        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9411        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9412        mContext.sendOrderedBroadcastAsUser(intent,
9413                UserHandle.ALL, null, br, mHandler, 0, null, null);
9414        */
9415        br.onReceive(mContext, intent);
9416    }
9417
9418    private long getLowRamTimeSinceIdle(long now) {
9419        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9420    }
9421
9422    @Override
9423    public void performIdleMaintenance() {
9424        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9425                != PackageManager.PERMISSION_GRANTED) {
9426            throw new SecurityException("Requires permission "
9427                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9428        }
9429
9430        synchronized (this) {
9431            final long now = SystemClock.uptimeMillis();
9432            final long timeSinceLastIdle = now - mLastIdleTime;
9433            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9434            mLastIdleTime = now;
9435            mLowRamTimeSinceLastIdle = 0;
9436            if (mLowRamStartTime != 0) {
9437                mLowRamStartTime = now;
9438            }
9439
9440            StringBuilder sb = new StringBuilder(128);
9441            sb.append("Idle maintenance over ");
9442            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9443            sb.append(" low RAM for ");
9444            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9445            Slog.i(TAG, sb.toString());
9446
9447            // If at least 1/3 of our time since the last idle period has been spent
9448            // with RAM low, then we want to kill processes.
9449            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9450
9451            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9452                ProcessRecord proc = mLruProcesses.get(i);
9453                if (proc.notCachedSinceIdle) {
9454                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9455                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9456                        if (doKilling && proc.initialIdlePss != 0
9457                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9458                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9459                                    + " from " + proc.initialIdlePss + ")");
9460                        }
9461                    }
9462                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9463                    proc.notCachedSinceIdle = true;
9464                    proc.initialIdlePss = 0;
9465                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9466                            isSleeping(), now);
9467                }
9468            }
9469
9470            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9471            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9472        }
9473    }
9474
9475    private void retrieveSettings() {
9476        final ContentResolver resolver = mContext.getContentResolver();
9477        String debugApp = Settings.Global.getString(
9478            resolver, Settings.Global.DEBUG_APP);
9479        boolean waitForDebugger = Settings.Global.getInt(
9480            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9481        boolean alwaysFinishActivities = Settings.Global.getInt(
9482            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9483        boolean forceRtl = Settings.Global.getInt(
9484                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9485        // Transfer any global setting for forcing RTL layout, into a System Property
9486        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9487
9488        Configuration configuration = new Configuration();
9489        Settings.System.getConfiguration(resolver, configuration);
9490        if (forceRtl) {
9491            // This will take care of setting the correct layout direction flags
9492            configuration.setLayoutDirection(configuration.locale);
9493        }
9494
9495        synchronized (this) {
9496            mDebugApp = mOrigDebugApp = debugApp;
9497            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9498            mAlwaysFinishActivities = alwaysFinishActivities;
9499            // This happens before any activities are started, so we can
9500            // change mConfiguration in-place.
9501            updateConfigurationLocked(configuration, null, false, true);
9502            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9503        }
9504    }
9505
9506    public boolean testIsSystemReady() {
9507        // no need to synchronize(this) just to read & return the value
9508        return mSystemReady;
9509    }
9510
9511    private static File getCalledPreBootReceiversFile() {
9512        File dataDir = Environment.getDataDirectory();
9513        File systemDir = new File(dataDir, "system");
9514        File fname = new File(systemDir, "called_pre_boots.dat");
9515        return fname;
9516    }
9517
9518    static final int LAST_DONE_VERSION = 10000;
9519
9520    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9521        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9522        File file = getCalledPreBootReceiversFile();
9523        FileInputStream fis = null;
9524        try {
9525            fis = new FileInputStream(file);
9526            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9527            int fvers = dis.readInt();
9528            if (fvers == LAST_DONE_VERSION) {
9529                String vers = dis.readUTF();
9530                String codename = dis.readUTF();
9531                String build = dis.readUTF();
9532                if (android.os.Build.VERSION.RELEASE.equals(vers)
9533                        && android.os.Build.VERSION.CODENAME.equals(codename)
9534                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9535                    int num = dis.readInt();
9536                    while (num > 0) {
9537                        num--;
9538                        String pkg = dis.readUTF();
9539                        String cls = dis.readUTF();
9540                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9541                    }
9542                }
9543            }
9544        } catch (FileNotFoundException e) {
9545        } catch (IOException e) {
9546            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9547        } finally {
9548            if (fis != null) {
9549                try {
9550                    fis.close();
9551                } catch (IOException e) {
9552                }
9553            }
9554        }
9555        return lastDoneReceivers;
9556    }
9557
9558    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9559        File file = getCalledPreBootReceiversFile();
9560        FileOutputStream fos = null;
9561        DataOutputStream dos = null;
9562        try {
9563            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9564            fos = new FileOutputStream(file);
9565            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9566            dos.writeInt(LAST_DONE_VERSION);
9567            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9568            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9569            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9570            dos.writeInt(list.size());
9571            for (int i=0; i<list.size(); i++) {
9572                dos.writeUTF(list.get(i).getPackageName());
9573                dos.writeUTF(list.get(i).getClassName());
9574            }
9575        } catch (IOException e) {
9576            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9577            file.delete();
9578        } finally {
9579            FileUtils.sync(fos);
9580            if (dos != null) {
9581                try {
9582                    dos.close();
9583                } catch (IOException e) {
9584                    // TODO Auto-generated catch block
9585                    e.printStackTrace();
9586                }
9587            }
9588        }
9589    }
9590
9591    public void systemReady(final Runnable goingCallback) {
9592        synchronized(this) {
9593            if (mSystemReady) {
9594                if (goingCallback != null) goingCallback.run();
9595                return;
9596            }
9597
9598            if (mRecentTasks == null) {
9599                mRecentTasks = mTaskPersister.restoreTasksLocked();
9600                if (!mRecentTasks.isEmpty()) {
9601                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9602                }
9603                mTaskPersister.startPersisting();
9604            }
9605
9606            // Check to see if there are any update receivers to run.
9607            if (!mDidUpdate) {
9608                if (mWaitingUpdate) {
9609                    return;
9610                }
9611                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9612                List<ResolveInfo> ris = null;
9613                try {
9614                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9615                            intent, null, 0, 0);
9616                } catch (RemoteException e) {
9617                }
9618                if (ris != null) {
9619                    for (int i=ris.size()-1; i>=0; i--) {
9620                        if ((ris.get(i).activityInfo.applicationInfo.flags
9621                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9622                            ris.remove(i);
9623                        }
9624                    }
9625                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9626
9627                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9628
9629                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9630                    for (int i=0; i<ris.size(); i++) {
9631                        ActivityInfo ai = ris.get(i).activityInfo;
9632                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9633                        if (lastDoneReceivers.contains(comp)) {
9634                            // We already did the pre boot receiver for this app with the current
9635                            // platform version, so don't do it again...
9636                            ris.remove(i);
9637                            i--;
9638                            // ...however, do keep it as one that has been done, so we don't
9639                            // forget about it when rewriting the file of last done receivers.
9640                            doneReceivers.add(comp);
9641                        }
9642                    }
9643
9644                    final int[] users = getUsersLocked();
9645                    for (int i=0; i<ris.size(); i++) {
9646                        ActivityInfo ai = ris.get(i).activityInfo;
9647                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9648                        doneReceivers.add(comp);
9649                        intent.setComponent(comp);
9650                        for (int j=0; j<users.length; j++) {
9651                            IIntentReceiver finisher = null;
9652                            if (i == ris.size()-1 && j == users.length-1) {
9653                                finisher = new IIntentReceiver.Stub() {
9654                                    public void performReceive(Intent intent, int resultCode,
9655                                            String data, Bundle extras, boolean ordered,
9656                                            boolean sticky, int sendingUser) {
9657                                        // The raw IIntentReceiver interface is called
9658                                        // with the AM lock held, so redispatch to
9659                                        // execute our code without the lock.
9660                                        mHandler.post(new Runnable() {
9661                                            public void run() {
9662                                                synchronized (ActivityManagerService.this) {
9663                                                    mDidUpdate = true;
9664                                                }
9665                                                writeLastDonePreBootReceivers(doneReceivers);
9666                                                showBootMessage(mContext.getText(
9667                                                        R.string.android_upgrading_complete),
9668                                                        false);
9669                                                systemReady(goingCallback);
9670                                            }
9671                                        });
9672                                    }
9673                                };
9674                            }
9675                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9676                                    + " for user " + users[j]);
9677                            broadcastIntentLocked(null, null, intent, null, finisher,
9678                                    0, null, null, null, AppOpsManager.OP_NONE,
9679                                    true, false, MY_PID, Process.SYSTEM_UID,
9680                                    users[j]);
9681                            if (finisher != null) {
9682                                mWaitingUpdate = true;
9683                            }
9684                        }
9685                    }
9686                }
9687                if (mWaitingUpdate) {
9688                    return;
9689                }
9690                mDidUpdate = true;
9691            }
9692
9693            mAppOpsService.systemReady();
9694            mUsageStatsService.systemReady();
9695            mSystemReady = true;
9696        }
9697
9698        ArrayList<ProcessRecord> procsToKill = null;
9699        synchronized(mPidsSelfLocked) {
9700            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9701                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9702                if (!isAllowedWhileBooting(proc.info)){
9703                    if (procsToKill == null) {
9704                        procsToKill = new ArrayList<ProcessRecord>();
9705                    }
9706                    procsToKill.add(proc);
9707                }
9708            }
9709        }
9710
9711        synchronized(this) {
9712            if (procsToKill != null) {
9713                for (int i=procsToKill.size()-1; i>=0; i--) {
9714                    ProcessRecord proc = procsToKill.get(i);
9715                    Slog.i(TAG, "Removing system update proc: " + proc);
9716                    removeProcessLocked(proc, true, false, "system update done");
9717                }
9718            }
9719
9720            // Now that we have cleaned up any update processes, we
9721            // are ready to start launching real processes and know that
9722            // we won't trample on them any more.
9723            mProcessesReady = true;
9724        }
9725
9726        Slog.i(TAG, "System now ready");
9727        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9728            SystemClock.uptimeMillis());
9729
9730        synchronized(this) {
9731            // Make sure we have no pre-ready processes sitting around.
9732
9733            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9734                ResolveInfo ri = mContext.getPackageManager()
9735                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9736                                STOCK_PM_FLAGS);
9737                CharSequence errorMsg = null;
9738                if (ri != null) {
9739                    ActivityInfo ai = ri.activityInfo;
9740                    ApplicationInfo app = ai.applicationInfo;
9741                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9742                        mTopAction = Intent.ACTION_FACTORY_TEST;
9743                        mTopData = null;
9744                        mTopComponent = new ComponentName(app.packageName,
9745                                ai.name);
9746                    } else {
9747                        errorMsg = mContext.getResources().getText(
9748                                com.android.internal.R.string.factorytest_not_system);
9749                    }
9750                } else {
9751                    errorMsg = mContext.getResources().getText(
9752                            com.android.internal.R.string.factorytest_no_action);
9753                }
9754                if (errorMsg != null) {
9755                    mTopAction = null;
9756                    mTopData = null;
9757                    mTopComponent = null;
9758                    Message msg = Message.obtain();
9759                    msg.what = SHOW_FACTORY_ERROR_MSG;
9760                    msg.getData().putCharSequence("msg", errorMsg);
9761                    mHandler.sendMessage(msg);
9762                }
9763            }
9764        }
9765
9766        retrieveSettings();
9767
9768        synchronized (this) {
9769            readGrantedUriPermissionsLocked();
9770        }
9771
9772        if (goingCallback != null) goingCallback.run();
9773
9774        mSystemServiceManager.startUser(mCurrentUserId);
9775
9776        synchronized (this) {
9777            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9778                try {
9779                    List apps = AppGlobals.getPackageManager().
9780                        getPersistentApplications(STOCK_PM_FLAGS);
9781                    if (apps != null) {
9782                        int N = apps.size();
9783                        int i;
9784                        for (i=0; i<N; i++) {
9785                            ApplicationInfo info
9786                                = (ApplicationInfo)apps.get(i);
9787                            if (info != null &&
9788                                    !info.packageName.equals("android")) {
9789                                addAppLocked(info, false);
9790                            }
9791                        }
9792                    }
9793                } catch (RemoteException ex) {
9794                    // pm is in same process, this will never happen.
9795                }
9796            }
9797
9798            // Start up initial activity.
9799            mBooting = true;
9800
9801            try {
9802                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9803                    Message msg = Message.obtain();
9804                    msg.what = SHOW_UID_ERROR_MSG;
9805                    mHandler.sendMessage(msg);
9806                }
9807            } catch (RemoteException e) {
9808            }
9809
9810            long ident = Binder.clearCallingIdentity();
9811            try {
9812                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9813                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9814                        | Intent.FLAG_RECEIVER_FOREGROUND);
9815                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9816                broadcastIntentLocked(null, null, intent,
9817                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9818                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9819                intent = new Intent(Intent.ACTION_USER_STARTING);
9820                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9821                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9822                broadcastIntentLocked(null, null, intent,
9823                        null, new IIntentReceiver.Stub() {
9824                            @Override
9825                            public void performReceive(Intent intent, int resultCode, String data,
9826                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9827                                    throws RemoteException {
9828                            }
9829                        }, 0, null, null,
9830                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9831                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9832            } catch (Throwable t) {
9833                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9834            } finally {
9835                Binder.restoreCallingIdentity(ident);
9836            }
9837            mStackSupervisor.resumeTopActivitiesLocked();
9838            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9839        }
9840    }
9841
9842    private boolean makeAppCrashingLocked(ProcessRecord app,
9843            String shortMsg, String longMsg, String stackTrace) {
9844        app.crashing = true;
9845        app.crashingReport = generateProcessError(app,
9846                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9847        startAppProblemLocked(app);
9848        app.stopFreezingAllLocked();
9849        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9850    }
9851
9852    private void makeAppNotRespondingLocked(ProcessRecord app,
9853            String activity, String shortMsg, String longMsg) {
9854        app.notResponding = true;
9855        app.notRespondingReport = generateProcessError(app,
9856                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9857                activity, shortMsg, longMsg, null);
9858        startAppProblemLocked(app);
9859        app.stopFreezingAllLocked();
9860    }
9861
9862    /**
9863     * Generate a process error record, suitable for attachment to a ProcessRecord.
9864     *
9865     * @param app The ProcessRecord in which the error occurred.
9866     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9867     *                      ActivityManager.AppErrorStateInfo
9868     * @param activity The activity associated with the crash, if known.
9869     * @param shortMsg Short message describing the crash.
9870     * @param longMsg Long message describing the crash.
9871     * @param stackTrace Full crash stack trace, may be null.
9872     *
9873     * @return Returns a fully-formed AppErrorStateInfo record.
9874     */
9875    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9876            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9877        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9878
9879        report.condition = condition;
9880        report.processName = app.processName;
9881        report.pid = app.pid;
9882        report.uid = app.info.uid;
9883        report.tag = activity;
9884        report.shortMsg = shortMsg;
9885        report.longMsg = longMsg;
9886        report.stackTrace = stackTrace;
9887
9888        return report;
9889    }
9890
9891    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9892        synchronized (this) {
9893            app.crashing = false;
9894            app.crashingReport = null;
9895            app.notResponding = false;
9896            app.notRespondingReport = null;
9897            if (app.anrDialog == fromDialog) {
9898                app.anrDialog = null;
9899            }
9900            if (app.waitDialog == fromDialog) {
9901                app.waitDialog = null;
9902            }
9903            if (app.pid > 0 && app.pid != MY_PID) {
9904                handleAppCrashLocked(app, null, null, null);
9905                killUnneededProcessLocked(app, "user request after error");
9906            }
9907        }
9908    }
9909
9910    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9911            String stackTrace) {
9912        long now = SystemClock.uptimeMillis();
9913
9914        Long crashTime;
9915        if (!app.isolated) {
9916            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9917        } else {
9918            crashTime = null;
9919        }
9920        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9921            // This process loses!
9922            Slog.w(TAG, "Process " + app.info.processName
9923                    + " has crashed too many times: killing!");
9924            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9925                    app.userId, app.info.processName, app.uid);
9926            mStackSupervisor.handleAppCrashLocked(app);
9927            if (!app.persistent) {
9928                // We don't want to start this process again until the user
9929                // explicitly does so...  but for persistent process, we really
9930                // need to keep it running.  If a persistent process is actually
9931                // repeatedly crashing, then badness for everyone.
9932                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9933                        app.info.processName);
9934                if (!app.isolated) {
9935                    // XXX We don't have a way to mark isolated processes
9936                    // as bad, since they don't have a peristent identity.
9937                    mBadProcesses.put(app.info.processName, app.uid,
9938                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9939                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9940                }
9941                app.bad = true;
9942                app.removed = true;
9943                // Don't let services in this process be restarted and potentially
9944                // annoy the user repeatedly.  Unless it is persistent, since those
9945                // processes run critical code.
9946                removeProcessLocked(app, false, false, "crash");
9947                mStackSupervisor.resumeTopActivitiesLocked();
9948                return false;
9949            }
9950            mStackSupervisor.resumeTopActivitiesLocked();
9951        } else {
9952            mStackSupervisor.finishTopRunningActivityLocked(app);
9953        }
9954
9955        // Bump up the crash count of any services currently running in the proc.
9956        for (int i=app.services.size()-1; i>=0; i--) {
9957            // Any services running in the application need to be placed
9958            // back in the pending list.
9959            ServiceRecord sr = app.services.valueAt(i);
9960            sr.crashCount++;
9961        }
9962
9963        // If the crashing process is what we consider to be the "home process" and it has been
9964        // replaced by a third-party app, clear the package preferred activities from packages
9965        // with a home activity running in the process to prevent a repeatedly crashing app
9966        // from blocking the user to manually clear the list.
9967        final ArrayList<ActivityRecord> activities = app.activities;
9968        if (app == mHomeProcess && activities.size() > 0
9969                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9970            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9971                final ActivityRecord r = activities.get(activityNdx);
9972                if (r.isHomeActivity()) {
9973                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9974                    try {
9975                        ActivityThread.getPackageManager()
9976                                .clearPackagePreferredActivities(r.packageName);
9977                    } catch (RemoteException c) {
9978                        // pm is in same process, this will never happen.
9979                    }
9980                }
9981            }
9982        }
9983
9984        if (!app.isolated) {
9985            // XXX Can't keep track of crash times for isolated processes,
9986            // because they don't have a perisistent identity.
9987            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9988        }
9989
9990        return true;
9991    }
9992
9993    void startAppProblemLocked(ProcessRecord app) {
9994        if (app.userId == mCurrentUserId) {
9995            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9996                    mContext, app.info.packageName, app.info.flags);
9997        } else {
9998            // If this app is not running under the current user, then we
9999            // can't give it a report button because that would require
10000            // launching the report UI under a different user.
10001            app.errorReportReceiver = null;
10002        }
10003        skipCurrentReceiverLocked(app);
10004    }
10005
10006    void skipCurrentReceiverLocked(ProcessRecord app) {
10007        for (BroadcastQueue queue : mBroadcastQueues) {
10008            queue.skipCurrentReceiverLocked(app);
10009        }
10010    }
10011
10012    /**
10013     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10014     * The application process will exit immediately after this call returns.
10015     * @param app object of the crashing app, null for the system server
10016     * @param crashInfo describing the exception
10017     */
10018    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10019        ProcessRecord r = findAppProcess(app, "Crash");
10020        final String processName = app == null ? "system_server"
10021                : (r == null ? "unknown" : r.processName);
10022
10023        handleApplicationCrashInner("crash", r, processName, crashInfo);
10024    }
10025
10026    /* Native crash reporting uses this inner version because it needs to be somewhat
10027     * decoupled from the AM-managed cleanup lifecycle
10028     */
10029    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10030            ApplicationErrorReport.CrashInfo crashInfo) {
10031        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10032                UserHandle.getUserId(Binder.getCallingUid()), processName,
10033                r == null ? -1 : r.info.flags,
10034                crashInfo.exceptionClassName,
10035                crashInfo.exceptionMessage,
10036                crashInfo.throwFileName,
10037                crashInfo.throwLineNumber);
10038
10039        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10040
10041        crashApplication(r, crashInfo);
10042    }
10043
10044    public void handleApplicationStrictModeViolation(
10045            IBinder app,
10046            int violationMask,
10047            StrictMode.ViolationInfo info) {
10048        ProcessRecord r = findAppProcess(app, "StrictMode");
10049        if (r == null) {
10050            return;
10051        }
10052
10053        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10054            Integer stackFingerprint = info.hashCode();
10055            boolean logIt = true;
10056            synchronized (mAlreadyLoggedViolatedStacks) {
10057                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10058                    logIt = false;
10059                    // TODO: sub-sample into EventLog for these, with
10060                    // the info.durationMillis?  Then we'd get
10061                    // the relative pain numbers, without logging all
10062                    // the stack traces repeatedly.  We'd want to do
10063                    // likewise in the client code, which also does
10064                    // dup suppression, before the Binder call.
10065                } else {
10066                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10067                        mAlreadyLoggedViolatedStacks.clear();
10068                    }
10069                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10070                }
10071            }
10072            if (logIt) {
10073                logStrictModeViolationToDropBox(r, info);
10074            }
10075        }
10076
10077        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10078            AppErrorResult result = new AppErrorResult();
10079            synchronized (this) {
10080                final long origId = Binder.clearCallingIdentity();
10081
10082                Message msg = Message.obtain();
10083                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10084                HashMap<String, Object> data = new HashMap<String, Object>();
10085                data.put("result", result);
10086                data.put("app", r);
10087                data.put("violationMask", violationMask);
10088                data.put("info", info);
10089                msg.obj = data;
10090                mHandler.sendMessage(msg);
10091
10092                Binder.restoreCallingIdentity(origId);
10093            }
10094            int res = result.get();
10095            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10096        }
10097    }
10098
10099    // Depending on the policy in effect, there could be a bunch of
10100    // these in quick succession so we try to batch these together to
10101    // minimize disk writes, number of dropbox entries, and maximize
10102    // compression, by having more fewer, larger records.
10103    private void logStrictModeViolationToDropBox(
10104            ProcessRecord process,
10105            StrictMode.ViolationInfo info) {
10106        if (info == null) {
10107            return;
10108        }
10109        final boolean isSystemApp = process == null ||
10110                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10111                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10112        final String processName = process == null ? "unknown" : process.processName;
10113        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10114        final DropBoxManager dbox = (DropBoxManager)
10115                mContext.getSystemService(Context.DROPBOX_SERVICE);
10116
10117        // Exit early if the dropbox isn't configured to accept this report type.
10118        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10119
10120        boolean bufferWasEmpty;
10121        boolean needsFlush;
10122        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10123        synchronized (sb) {
10124            bufferWasEmpty = sb.length() == 0;
10125            appendDropBoxProcessHeaders(process, processName, sb);
10126            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10127            sb.append("System-App: ").append(isSystemApp).append("\n");
10128            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10129            if (info.violationNumThisLoop != 0) {
10130                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10131            }
10132            if (info.numAnimationsRunning != 0) {
10133                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10134            }
10135            if (info.broadcastIntentAction != null) {
10136                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10137            }
10138            if (info.durationMillis != -1) {
10139                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10140            }
10141            if (info.numInstances != -1) {
10142                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10143            }
10144            if (info.tags != null) {
10145                for (String tag : info.tags) {
10146                    sb.append("Span-Tag: ").append(tag).append("\n");
10147                }
10148            }
10149            sb.append("\n");
10150            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10151                sb.append(info.crashInfo.stackTrace);
10152            }
10153            sb.append("\n");
10154
10155            // Only buffer up to ~64k.  Various logging bits truncate
10156            // things at 128k.
10157            needsFlush = (sb.length() > 64 * 1024);
10158        }
10159
10160        // Flush immediately if the buffer's grown too large, or this
10161        // is a non-system app.  Non-system apps are isolated with a
10162        // different tag & policy and not batched.
10163        //
10164        // Batching is useful during internal testing with
10165        // StrictMode settings turned up high.  Without batching,
10166        // thousands of separate files could be created on boot.
10167        if (!isSystemApp || needsFlush) {
10168            new Thread("Error dump: " + dropboxTag) {
10169                @Override
10170                public void run() {
10171                    String report;
10172                    synchronized (sb) {
10173                        report = sb.toString();
10174                        sb.delete(0, sb.length());
10175                        sb.trimToSize();
10176                    }
10177                    if (report.length() != 0) {
10178                        dbox.addText(dropboxTag, report);
10179                    }
10180                }
10181            }.start();
10182            return;
10183        }
10184
10185        // System app batching:
10186        if (!bufferWasEmpty) {
10187            // An existing dropbox-writing thread is outstanding, so
10188            // we don't need to start it up.  The existing thread will
10189            // catch the buffer appends we just did.
10190            return;
10191        }
10192
10193        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10194        // (After this point, we shouldn't access AMS internal data structures.)
10195        new Thread("Error dump: " + dropboxTag) {
10196            @Override
10197            public void run() {
10198                // 5 second sleep to let stacks arrive and be batched together
10199                try {
10200                    Thread.sleep(5000);  // 5 seconds
10201                } catch (InterruptedException e) {}
10202
10203                String errorReport;
10204                synchronized (mStrictModeBuffer) {
10205                    errorReport = mStrictModeBuffer.toString();
10206                    if (errorReport.length() == 0) {
10207                        return;
10208                    }
10209                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10210                    mStrictModeBuffer.trimToSize();
10211                }
10212                dbox.addText(dropboxTag, errorReport);
10213            }
10214        }.start();
10215    }
10216
10217    /**
10218     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10219     * @param app object of the crashing app, null for the system server
10220     * @param tag reported by the caller
10221     * @param crashInfo describing the context of the error
10222     * @return true if the process should exit immediately (WTF is fatal)
10223     */
10224    public boolean handleApplicationWtf(IBinder app, String tag,
10225            ApplicationErrorReport.CrashInfo crashInfo) {
10226        ProcessRecord r = findAppProcess(app, "WTF");
10227        final String processName = app == null ? "system_server"
10228                : (r == null ? "unknown" : r.processName);
10229
10230        EventLog.writeEvent(EventLogTags.AM_WTF,
10231                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10232                processName,
10233                r == null ? -1 : r.info.flags,
10234                tag, crashInfo.exceptionMessage);
10235
10236        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10237
10238        if (r != null && r.pid != Process.myPid() &&
10239                Settings.Global.getInt(mContext.getContentResolver(),
10240                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10241            crashApplication(r, crashInfo);
10242            return true;
10243        } else {
10244            return false;
10245        }
10246    }
10247
10248    /**
10249     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10250     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10251     */
10252    private ProcessRecord findAppProcess(IBinder app, String reason) {
10253        if (app == null) {
10254            return null;
10255        }
10256
10257        synchronized (this) {
10258            final int NP = mProcessNames.getMap().size();
10259            for (int ip=0; ip<NP; ip++) {
10260                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10261                final int NA = apps.size();
10262                for (int ia=0; ia<NA; ia++) {
10263                    ProcessRecord p = apps.valueAt(ia);
10264                    if (p.thread != null && p.thread.asBinder() == app) {
10265                        return p;
10266                    }
10267                }
10268            }
10269
10270            Slog.w(TAG, "Can't find mystery application for " + reason
10271                    + " from pid=" + Binder.getCallingPid()
10272                    + " uid=" + Binder.getCallingUid() + ": " + app);
10273            return null;
10274        }
10275    }
10276
10277    /**
10278     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10279     * to append various headers to the dropbox log text.
10280     */
10281    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10282            StringBuilder sb) {
10283        // Watchdog thread ends up invoking this function (with
10284        // a null ProcessRecord) to add the stack file to dropbox.
10285        // Do not acquire a lock on this (am) in such cases, as it
10286        // could cause a potential deadlock, if and when watchdog
10287        // is invoked due to unavailability of lock on am and it
10288        // would prevent watchdog from killing system_server.
10289        if (process == null) {
10290            sb.append("Process: ").append(processName).append("\n");
10291            return;
10292        }
10293        // Note: ProcessRecord 'process' is guarded by the service
10294        // instance.  (notably process.pkgList, which could otherwise change
10295        // concurrently during execution of this method)
10296        synchronized (this) {
10297            sb.append("Process: ").append(processName).append("\n");
10298            int flags = process.info.flags;
10299            IPackageManager pm = AppGlobals.getPackageManager();
10300            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10301            for (int ip=0; ip<process.pkgList.size(); ip++) {
10302                String pkg = process.pkgList.keyAt(ip);
10303                sb.append("Package: ").append(pkg);
10304                try {
10305                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10306                    if (pi != null) {
10307                        sb.append(" v").append(pi.versionCode);
10308                        if (pi.versionName != null) {
10309                            sb.append(" (").append(pi.versionName).append(")");
10310                        }
10311                    }
10312                } catch (RemoteException e) {
10313                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10314                }
10315                sb.append("\n");
10316            }
10317        }
10318    }
10319
10320    private static String processClass(ProcessRecord process) {
10321        if (process == null || process.pid == MY_PID) {
10322            return "system_server";
10323        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10324            return "system_app";
10325        } else {
10326            return "data_app";
10327        }
10328    }
10329
10330    /**
10331     * Write a description of an error (crash, WTF, ANR) to the drop box.
10332     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10333     * @param process which caused the error, null means the system server
10334     * @param activity which triggered the error, null if unknown
10335     * @param parent activity related to the error, null if unknown
10336     * @param subject line related to the error, null if absent
10337     * @param report in long form describing the error, null if absent
10338     * @param logFile to include in the report, null if none
10339     * @param crashInfo giving an application stack trace, null if absent
10340     */
10341    public void addErrorToDropBox(String eventType,
10342            ProcessRecord process, String processName, ActivityRecord activity,
10343            ActivityRecord parent, String subject,
10344            final String report, final File logFile,
10345            final ApplicationErrorReport.CrashInfo crashInfo) {
10346        // NOTE -- this must never acquire the ActivityManagerService lock,
10347        // otherwise the watchdog may be prevented from resetting the system.
10348
10349        final String dropboxTag = processClass(process) + "_" + eventType;
10350        final DropBoxManager dbox = (DropBoxManager)
10351                mContext.getSystemService(Context.DROPBOX_SERVICE);
10352
10353        // Exit early if the dropbox isn't configured to accept this report type.
10354        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10355
10356        final StringBuilder sb = new StringBuilder(1024);
10357        appendDropBoxProcessHeaders(process, processName, sb);
10358        if (activity != null) {
10359            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10360        }
10361        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10362            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10363        }
10364        if (parent != null && parent != activity) {
10365            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10366        }
10367        if (subject != null) {
10368            sb.append("Subject: ").append(subject).append("\n");
10369        }
10370        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10371        if (Debug.isDebuggerConnected()) {
10372            sb.append("Debugger: Connected\n");
10373        }
10374        sb.append("\n");
10375
10376        // Do the rest in a worker thread to avoid blocking the caller on I/O
10377        // (After this point, we shouldn't access AMS internal data structures.)
10378        Thread worker = new Thread("Error dump: " + dropboxTag) {
10379            @Override
10380            public void run() {
10381                if (report != null) {
10382                    sb.append(report);
10383                }
10384                if (logFile != null) {
10385                    try {
10386                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10387                                    "\n\n[[TRUNCATED]]"));
10388                    } catch (IOException e) {
10389                        Slog.e(TAG, "Error reading " + logFile, e);
10390                    }
10391                }
10392                if (crashInfo != null && crashInfo.stackTrace != null) {
10393                    sb.append(crashInfo.stackTrace);
10394                }
10395
10396                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10397                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10398                if (lines > 0) {
10399                    sb.append("\n");
10400
10401                    // Merge several logcat streams, and take the last N lines
10402                    InputStreamReader input = null;
10403                    try {
10404                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10405                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10406                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10407
10408                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10409                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10410                        input = new InputStreamReader(logcat.getInputStream());
10411
10412                        int num;
10413                        char[] buf = new char[8192];
10414                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10415                    } catch (IOException e) {
10416                        Slog.e(TAG, "Error running logcat", e);
10417                    } finally {
10418                        if (input != null) try { input.close(); } catch (IOException e) {}
10419                    }
10420                }
10421
10422                dbox.addText(dropboxTag, sb.toString());
10423            }
10424        };
10425
10426        if (process == null) {
10427            // If process is null, we are being called from some internal code
10428            // and may be about to die -- run this synchronously.
10429            worker.run();
10430        } else {
10431            worker.start();
10432        }
10433    }
10434
10435    /**
10436     * Bring up the "unexpected error" dialog box for a crashing app.
10437     * Deal with edge cases (intercepts from instrumented applications,
10438     * ActivityController, error intent receivers, that sort of thing).
10439     * @param r the application crashing
10440     * @param crashInfo describing the failure
10441     */
10442    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10443        long timeMillis = System.currentTimeMillis();
10444        String shortMsg = crashInfo.exceptionClassName;
10445        String longMsg = crashInfo.exceptionMessage;
10446        String stackTrace = crashInfo.stackTrace;
10447        if (shortMsg != null && longMsg != null) {
10448            longMsg = shortMsg + ": " + longMsg;
10449        } else if (shortMsg != null) {
10450            longMsg = shortMsg;
10451        }
10452
10453        AppErrorResult result = new AppErrorResult();
10454        synchronized (this) {
10455            if (mController != null) {
10456                try {
10457                    String name = r != null ? r.processName : null;
10458                    int pid = r != null ? r.pid : Binder.getCallingPid();
10459                    if (!mController.appCrashed(name, pid,
10460                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10461                        Slog.w(TAG, "Force-killing crashed app " + name
10462                                + " at watcher's request");
10463                        Process.killProcess(pid);
10464                        return;
10465                    }
10466                } catch (RemoteException e) {
10467                    mController = null;
10468                    Watchdog.getInstance().setActivityController(null);
10469                }
10470            }
10471
10472            final long origId = Binder.clearCallingIdentity();
10473
10474            // If this process is running instrumentation, finish it.
10475            if (r != null && r.instrumentationClass != null) {
10476                Slog.w(TAG, "Error in app " + r.processName
10477                      + " running instrumentation " + r.instrumentationClass + ":");
10478                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10479                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10480                Bundle info = new Bundle();
10481                info.putString("shortMsg", shortMsg);
10482                info.putString("longMsg", longMsg);
10483                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10484                Binder.restoreCallingIdentity(origId);
10485                return;
10486            }
10487
10488            // If we can't identify the process or it's already exceeded its crash quota,
10489            // quit right away without showing a crash dialog.
10490            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10491                Binder.restoreCallingIdentity(origId);
10492                return;
10493            }
10494
10495            Message msg = Message.obtain();
10496            msg.what = SHOW_ERROR_MSG;
10497            HashMap data = new HashMap();
10498            data.put("result", result);
10499            data.put("app", r);
10500            msg.obj = data;
10501            mHandler.sendMessage(msg);
10502
10503            Binder.restoreCallingIdentity(origId);
10504        }
10505
10506        int res = result.get();
10507
10508        Intent appErrorIntent = null;
10509        synchronized (this) {
10510            if (r != null && !r.isolated) {
10511                // XXX Can't keep track of crash time for isolated processes,
10512                // since they don't have a persistent identity.
10513                mProcessCrashTimes.put(r.info.processName, r.uid,
10514                        SystemClock.uptimeMillis());
10515            }
10516            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10517                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10518            }
10519        }
10520
10521        if (appErrorIntent != null) {
10522            try {
10523                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10524            } catch (ActivityNotFoundException e) {
10525                Slog.w(TAG, "bug report receiver dissappeared", e);
10526            }
10527        }
10528    }
10529
10530    Intent createAppErrorIntentLocked(ProcessRecord r,
10531            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10532        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10533        if (report == null) {
10534            return null;
10535        }
10536        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10537        result.setComponent(r.errorReportReceiver);
10538        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10539        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10540        return result;
10541    }
10542
10543    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10544            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10545        if (r.errorReportReceiver == null) {
10546            return null;
10547        }
10548
10549        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10550            return null;
10551        }
10552
10553        ApplicationErrorReport report = new ApplicationErrorReport();
10554        report.packageName = r.info.packageName;
10555        report.installerPackageName = r.errorReportReceiver.getPackageName();
10556        report.processName = r.processName;
10557        report.time = timeMillis;
10558        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10559
10560        if (r.crashing || r.forceCrashReport) {
10561            report.type = ApplicationErrorReport.TYPE_CRASH;
10562            report.crashInfo = crashInfo;
10563        } else if (r.notResponding) {
10564            report.type = ApplicationErrorReport.TYPE_ANR;
10565            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10566
10567            report.anrInfo.activity = r.notRespondingReport.tag;
10568            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10569            report.anrInfo.info = r.notRespondingReport.longMsg;
10570        }
10571
10572        return report;
10573    }
10574
10575    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10576        enforceNotIsolatedCaller("getProcessesInErrorState");
10577        // assume our apps are happy - lazy create the list
10578        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10579
10580        final boolean allUsers = ActivityManager.checkUidPermission(
10581                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10582                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10583        int userId = UserHandle.getUserId(Binder.getCallingUid());
10584
10585        synchronized (this) {
10586
10587            // iterate across all processes
10588            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10589                ProcessRecord app = mLruProcesses.get(i);
10590                if (!allUsers && app.userId != userId) {
10591                    continue;
10592                }
10593                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10594                    // This one's in trouble, so we'll generate a report for it
10595                    // crashes are higher priority (in case there's a crash *and* an anr)
10596                    ActivityManager.ProcessErrorStateInfo report = null;
10597                    if (app.crashing) {
10598                        report = app.crashingReport;
10599                    } else if (app.notResponding) {
10600                        report = app.notRespondingReport;
10601                    }
10602
10603                    if (report != null) {
10604                        if (errList == null) {
10605                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10606                        }
10607                        errList.add(report);
10608                    } else {
10609                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10610                                " crashing = " + app.crashing +
10611                                " notResponding = " + app.notResponding);
10612                    }
10613                }
10614            }
10615        }
10616
10617        return errList;
10618    }
10619
10620    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10621        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10622            if (currApp != null) {
10623                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10624            }
10625            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10626        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10627            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10628        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10629            if (currApp != null) {
10630                currApp.lru = 0;
10631            }
10632            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10633        } else if (adj >= ProcessList.SERVICE_ADJ) {
10634            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10635        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10636            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10637        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10638            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10639        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10640            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10641        } else {
10642            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10643        }
10644    }
10645
10646    private void fillInProcMemInfo(ProcessRecord app,
10647            ActivityManager.RunningAppProcessInfo outInfo) {
10648        outInfo.pid = app.pid;
10649        outInfo.uid = app.info.uid;
10650        if (mHeavyWeightProcess == app) {
10651            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10652        }
10653        if (app.persistent) {
10654            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10655        }
10656        if (app.activities.size() > 0) {
10657            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10658        }
10659        outInfo.lastTrimLevel = app.trimMemoryLevel;
10660        int adj = app.curAdj;
10661        outInfo.importance = oomAdjToImportance(adj, outInfo);
10662        outInfo.importanceReasonCode = app.adjTypeCode;
10663        outInfo.processState = app.curProcState;
10664    }
10665
10666    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10667        enforceNotIsolatedCaller("getRunningAppProcesses");
10668        // Lazy instantiation of list
10669        List<ActivityManager.RunningAppProcessInfo> runList = null;
10670        final boolean allUsers = ActivityManager.checkUidPermission(
10671                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10672                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10673        int userId = UserHandle.getUserId(Binder.getCallingUid());
10674        synchronized (this) {
10675            // Iterate across all processes
10676            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10677                ProcessRecord app = mLruProcesses.get(i);
10678                if (!allUsers && app.userId != userId) {
10679                    continue;
10680                }
10681                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10682                    // Generate process state info for running application
10683                    ActivityManager.RunningAppProcessInfo currApp =
10684                        new ActivityManager.RunningAppProcessInfo(app.processName,
10685                                app.pid, app.getPackageList());
10686                    fillInProcMemInfo(app, currApp);
10687                    if (app.adjSource instanceof ProcessRecord) {
10688                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10689                        currApp.importanceReasonImportance = oomAdjToImportance(
10690                                app.adjSourceOom, null);
10691                    } else if (app.adjSource instanceof ActivityRecord) {
10692                        ActivityRecord r = (ActivityRecord)app.adjSource;
10693                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10694                    }
10695                    if (app.adjTarget instanceof ComponentName) {
10696                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10697                    }
10698                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10699                    //        + " lru=" + currApp.lru);
10700                    if (runList == null) {
10701                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10702                    }
10703                    runList.add(currApp);
10704                }
10705            }
10706        }
10707        return runList;
10708    }
10709
10710    public List<ApplicationInfo> getRunningExternalApplications() {
10711        enforceNotIsolatedCaller("getRunningExternalApplications");
10712        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10713        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10714        if (runningApps != null && runningApps.size() > 0) {
10715            Set<String> extList = new HashSet<String>();
10716            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10717                if (app.pkgList != null) {
10718                    for (String pkg : app.pkgList) {
10719                        extList.add(pkg);
10720                    }
10721                }
10722            }
10723            IPackageManager pm = AppGlobals.getPackageManager();
10724            for (String pkg : extList) {
10725                try {
10726                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10727                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10728                        retList.add(info);
10729                    }
10730                } catch (RemoteException e) {
10731                }
10732            }
10733        }
10734        return retList;
10735    }
10736
10737    @Override
10738    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10739        enforceNotIsolatedCaller("getMyMemoryState");
10740        synchronized (this) {
10741            ProcessRecord proc;
10742            synchronized (mPidsSelfLocked) {
10743                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10744            }
10745            fillInProcMemInfo(proc, outInfo);
10746        }
10747    }
10748
10749    @Override
10750    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10751        if (checkCallingPermission(android.Manifest.permission.DUMP)
10752                != PackageManager.PERMISSION_GRANTED) {
10753            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10754                    + Binder.getCallingPid()
10755                    + ", uid=" + Binder.getCallingUid()
10756                    + " without permission "
10757                    + android.Manifest.permission.DUMP);
10758            return;
10759        }
10760
10761        boolean dumpAll = false;
10762        boolean dumpClient = false;
10763        String dumpPackage = null;
10764
10765        int opti = 0;
10766        while (opti < args.length) {
10767            String opt = args[opti];
10768            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10769                break;
10770            }
10771            opti++;
10772            if ("-a".equals(opt)) {
10773                dumpAll = true;
10774            } else if ("-c".equals(opt)) {
10775                dumpClient = true;
10776            } else if ("-h".equals(opt)) {
10777                pw.println("Activity manager dump options:");
10778                pw.println("  [-a] [-c] [-h] [cmd] ...");
10779                pw.println("  cmd may be one of:");
10780                pw.println("    a[ctivities]: activity stack state");
10781                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10782                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10783                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10784                pw.println("    o[om]: out of memory management");
10785                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10786                pw.println("    provider [COMP_SPEC]: provider client-side state");
10787                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10788                pw.println("    service [COMP_SPEC]: service client-side state");
10789                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10790                pw.println("    all: dump all activities");
10791                pw.println("    top: dump the top activity");
10792                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10793                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10794                pw.println("    a partial substring in a component name, a");
10795                pw.println("    hex object identifier.");
10796                pw.println("  -a: include all available server state.");
10797                pw.println("  -c: include client state.");
10798                return;
10799            } else {
10800                pw.println("Unknown argument: " + opt + "; use -h for help");
10801            }
10802        }
10803
10804        long origId = Binder.clearCallingIdentity();
10805        boolean more = false;
10806        // Is the caller requesting to dump a particular piece of data?
10807        if (opti < args.length) {
10808            String cmd = args[opti];
10809            opti++;
10810            if ("activities".equals(cmd) || "a".equals(cmd)) {
10811                synchronized (this) {
10812                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10813                }
10814            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10815                String[] newArgs;
10816                String name;
10817                if (opti >= args.length) {
10818                    name = null;
10819                    newArgs = EMPTY_STRING_ARRAY;
10820                } else {
10821                    name = args[opti];
10822                    opti++;
10823                    newArgs = new String[args.length - opti];
10824                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10825                            args.length - opti);
10826                }
10827                synchronized (this) {
10828                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10829                }
10830            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10831                String[] newArgs;
10832                String name;
10833                if (opti >= args.length) {
10834                    name = null;
10835                    newArgs = EMPTY_STRING_ARRAY;
10836                } else {
10837                    name = args[opti];
10838                    opti++;
10839                    newArgs = new String[args.length - opti];
10840                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10841                            args.length - opti);
10842                }
10843                synchronized (this) {
10844                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10845                }
10846            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10847                String[] newArgs;
10848                String name;
10849                if (opti >= args.length) {
10850                    name = null;
10851                    newArgs = EMPTY_STRING_ARRAY;
10852                } else {
10853                    name = args[opti];
10854                    opti++;
10855                    newArgs = new String[args.length - opti];
10856                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10857                            args.length - opti);
10858                }
10859                synchronized (this) {
10860                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10861                }
10862            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10863                synchronized (this) {
10864                    dumpOomLocked(fd, pw, args, opti, true);
10865                }
10866            } else if ("provider".equals(cmd)) {
10867                String[] newArgs;
10868                String name;
10869                if (opti >= args.length) {
10870                    name = null;
10871                    newArgs = EMPTY_STRING_ARRAY;
10872                } else {
10873                    name = args[opti];
10874                    opti++;
10875                    newArgs = new String[args.length - opti];
10876                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10877                }
10878                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10879                    pw.println("No providers match: " + name);
10880                    pw.println("Use -h for help.");
10881                }
10882            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10883                synchronized (this) {
10884                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10885                }
10886            } else if ("service".equals(cmd)) {
10887                String[] newArgs;
10888                String name;
10889                if (opti >= args.length) {
10890                    name = null;
10891                    newArgs = EMPTY_STRING_ARRAY;
10892                } else {
10893                    name = args[opti];
10894                    opti++;
10895                    newArgs = new String[args.length - opti];
10896                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10897                            args.length - opti);
10898                }
10899                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10900                    pw.println("No services match: " + name);
10901                    pw.println("Use -h for help.");
10902                }
10903            } else if ("package".equals(cmd)) {
10904                String[] newArgs;
10905                if (opti >= args.length) {
10906                    pw.println("package: no package name specified");
10907                    pw.println("Use -h for help.");
10908                } else {
10909                    dumpPackage = args[opti];
10910                    opti++;
10911                    newArgs = new String[args.length - opti];
10912                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10913                            args.length - opti);
10914                    args = newArgs;
10915                    opti = 0;
10916                    more = true;
10917                }
10918            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10919                synchronized (this) {
10920                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10921                }
10922            } else {
10923                // Dumping a single activity?
10924                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10925                    pw.println("Bad activity command, or no activities match: " + cmd);
10926                    pw.println("Use -h for help.");
10927                }
10928            }
10929            if (!more) {
10930                Binder.restoreCallingIdentity(origId);
10931                return;
10932            }
10933        }
10934
10935        // No piece of data specified, dump everything.
10936        synchronized (this) {
10937            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10938            pw.println();
10939            if (dumpAll) {
10940                pw.println("-------------------------------------------------------------------------------");
10941            }
10942            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10943            pw.println();
10944            if (dumpAll) {
10945                pw.println("-------------------------------------------------------------------------------");
10946            }
10947            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10948            pw.println();
10949            if (dumpAll) {
10950                pw.println("-------------------------------------------------------------------------------");
10951            }
10952            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10953            pw.println();
10954            if (dumpAll) {
10955                pw.println("-------------------------------------------------------------------------------");
10956            }
10957            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10958            pw.println();
10959            if (dumpAll) {
10960                pw.println("-------------------------------------------------------------------------------");
10961            }
10962            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10963        }
10964        Binder.restoreCallingIdentity(origId);
10965    }
10966
10967    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10968            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10969        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10970
10971        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10972                dumpPackage);
10973        boolean needSep = printedAnything;
10974
10975        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10976                dumpPackage, needSep, "  mFocusedActivity: ");
10977        if (printed) {
10978            printedAnything = true;
10979            needSep = false;
10980        }
10981
10982        if (dumpPackage == null) {
10983            if (needSep) {
10984                pw.println();
10985            }
10986            needSep = true;
10987            printedAnything = true;
10988            mStackSupervisor.dump(pw, "  ");
10989        }
10990
10991        if (mRecentTasks.size() > 0) {
10992            boolean printedHeader = false;
10993
10994            final int N = mRecentTasks.size();
10995            for (int i=0; i<N; i++) {
10996                TaskRecord tr = mRecentTasks.get(i);
10997                if (dumpPackage != null) {
10998                    if (tr.realActivity == null ||
10999                            !dumpPackage.equals(tr.realActivity)) {
11000                        continue;
11001                    }
11002                }
11003                if (!printedHeader) {
11004                    if (needSep) {
11005                        pw.println();
11006                    }
11007                    pw.println("  Recent tasks:");
11008                    printedHeader = true;
11009                    printedAnything = true;
11010                }
11011                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11012                        pw.println(tr);
11013                if (dumpAll) {
11014                    mRecentTasks.get(i).dump(pw, "    ");
11015                }
11016            }
11017        }
11018
11019        if (!printedAnything) {
11020            pw.println("  (nothing)");
11021        }
11022    }
11023
11024    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11025            int opti, boolean dumpAll, String dumpPackage) {
11026        boolean needSep = false;
11027        boolean printedAnything = false;
11028        int numPers = 0;
11029
11030        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11031
11032        if (dumpAll) {
11033            final int NP = mProcessNames.getMap().size();
11034            for (int ip=0; ip<NP; ip++) {
11035                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11036                final int NA = procs.size();
11037                for (int ia=0; ia<NA; ia++) {
11038                    ProcessRecord r = procs.valueAt(ia);
11039                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11040                        continue;
11041                    }
11042                    if (!needSep) {
11043                        pw.println("  All known processes:");
11044                        needSep = true;
11045                        printedAnything = true;
11046                    }
11047                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11048                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11049                        pw.print(" "); pw.println(r);
11050                    r.dump(pw, "    ");
11051                    if (r.persistent) {
11052                        numPers++;
11053                    }
11054                }
11055            }
11056        }
11057
11058        if (mIsolatedProcesses.size() > 0) {
11059            boolean printed = false;
11060            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11061                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11062                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11063                    continue;
11064                }
11065                if (!printed) {
11066                    if (needSep) {
11067                        pw.println();
11068                    }
11069                    pw.println("  Isolated process list (sorted by uid):");
11070                    printedAnything = true;
11071                    printed = true;
11072                    needSep = true;
11073                }
11074                pw.println(String.format("%sIsolated #%2d: %s",
11075                        "    ", i, r.toString()));
11076            }
11077        }
11078
11079        if (mLruProcesses.size() > 0) {
11080            if (needSep) {
11081                pw.println();
11082            }
11083            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11084                    pw.print(" total, non-act at ");
11085                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11086                    pw.print(", non-svc at ");
11087                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11088                    pw.println("):");
11089            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11090            needSep = true;
11091            printedAnything = true;
11092        }
11093
11094        if (dumpAll || dumpPackage != null) {
11095            synchronized (mPidsSelfLocked) {
11096                boolean printed = false;
11097                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11098                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11099                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11100                        continue;
11101                    }
11102                    if (!printed) {
11103                        if (needSep) pw.println();
11104                        needSep = true;
11105                        pw.println("  PID mappings:");
11106                        printed = true;
11107                        printedAnything = true;
11108                    }
11109                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11110                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11111                }
11112            }
11113        }
11114
11115        if (mForegroundProcesses.size() > 0) {
11116            synchronized (mPidsSelfLocked) {
11117                boolean printed = false;
11118                for (int i=0; i<mForegroundProcesses.size(); i++) {
11119                    ProcessRecord r = mPidsSelfLocked.get(
11120                            mForegroundProcesses.valueAt(i).pid);
11121                    if (dumpPackage != null && (r == null
11122                            || !r.pkgList.containsKey(dumpPackage))) {
11123                        continue;
11124                    }
11125                    if (!printed) {
11126                        if (needSep) pw.println();
11127                        needSep = true;
11128                        pw.println("  Foreground Processes:");
11129                        printed = true;
11130                        printedAnything = true;
11131                    }
11132                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11133                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11134                }
11135            }
11136        }
11137
11138        if (mPersistentStartingProcesses.size() > 0) {
11139            if (needSep) pw.println();
11140            needSep = true;
11141            printedAnything = true;
11142            pw.println("  Persisent processes that are starting:");
11143            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11144                    "Starting Norm", "Restarting PERS", dumpPackage);
11145        }
11146
11147        if (mRemovedProcesses.size() > 0) {
11148            if (needSep) pw.println();
11149            needSep = true;
11150            printedAnything = true;
11151            pw.println("  Processes that are being removed:");
11152            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11153                    "Removed Norm", "Removed PERS", dumpPackage);
11154        }
11155
11156        if (mProcessesOnHold.size() > 0) {
11157            if (needSep) pw.println();
11158            needSep = true;
11159            printedAnything = true;
11160            pw.println("  Processes that are on old until the system is ready:");
11161            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11162                    "OnHold Norm", "OnHold PERS", dumpPackage);
11163        }
11164
11165        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11166
11167        if (mProcessCrashTimes.getMap().size() > 0) {
11168            boolean printed = false;
11169            long now = SystemClock.uptimeMillis();
11170            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11171            final int NP = pmap.size();
11172            for (int ip=0; ip<NP; ip++) {
11173                String pname = pmap.keyAt(ip);
11174                SparseArray<Long> uids = pmap.valueAt(ip);
11175                final int N = uids.size();
11176                for (int i=0; i<N; i++) {
11177                    int puid = uids.keyAt(i);
11178                    ProcessRecord r = mProcessNames.get(pname, puid);
11179                    if (dumpPackage != null && (r == null
11180                            || !r.pkgList.containsKey(dumpPackage))) {
11181                        continue;
11182                    }
11183                    if (!printed) {
11184                        if (needSep) pw.println();
11185                        needSep = true;
11186                        pw.println("  Time since processes crashed:");
11187                        printed = true;
11188                        printedAnything = true;
11189                    }
11190                    pw.print("    Process "); pw.print(pname);
11191                            pw.print(" uid "); pw.print(puid);
11192                            pw.print(": last crashed ");
11193                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11194                            pw.println(" ago");
11195                }
11196            }
11197        }
11198
11199        if (mBadProcesses.getMap().size() > 0) {
11200            boolean printed = false;
11201            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11202            final int NP = pmap.size();
11203            for (int ip=0; ip<NP; ip++) {
11204                String pname = pmap.keyAt(ip);
11205                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11206                final int N = uids.size();
11207                for (int i=0; i<N; i++) {
11208                    int puid = uids.keyAt(i);
11209                    ProcessRecord r = mProcessNames.get(pname, puid);
11210                    if (dumpPackage != null && (r == null
11211                            || !r.pkgList.containsKey(dumpPackage))) {
11212                        continue;
11213                    }
11214                    if (!printed) {
11215                        if (needSep) pw.println();
11216                        needSep = true;
11217                        pw.println("  Bad processes:");
11218                        printedAnything = true;
11219                    }
11220                    BadProcessInfo info = uids.valueAt(i);
11221                    pw.print("    Bad process "); pw.print(pname);
11222                            pw.print(" uid "); pw.print(puid);
11223                            pw.print(": crashed at time "); pw.println(info.time);
11224                    if (info.shortMsg != null) {
11225                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11226                    }
11227                    if (info.longMsg != null) {
11228                        pw.print("      Long msg: "); pw.println(info.longMsg);
11229                    }
11230                    if (info.stack != null) {
11231                        pw.println("      Stack:");
11232                        int lastPos = 0;
11233                        for (int pos=0; pos<info.stack.length(); pos++) {
11234                            if (info.stack.charAt(pos) == '\n') {
11235                                pw.print("        ");
11236                                pw.write(info.stack, lastPos, pos-lastPos);
11237                                pw.println();
11238                                lastPos = pos+1;
11239                            }
11240                        }
11241                        if (lastPos < info.stack.length()) {
11242                            pw.print("        ");
11243                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11244                            pw.println();
11245                        }
11246                    }
11247                }
11248            }
11249        }
11250
11251        if (dumpPackage == null) {
11252            pw.println();
11253            needSep = false;
11254            pw.println("  mStartedUsers:");
11255            for (int i=0; i<mStartedUsers.size(); i++) {
11256                UserStartedState uss = mStartedUsers.valueAt(i);
11257                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11258                        pw.print(": "); uss.dump("", pw);
11259            }
11260            pw.print("  mStartedUserArray: [");
11261            for (int i=0; i<mStartedUserArray.length; i++) {
11262                if (i > 0) pw.print(", ");
11263                pw.print(mStartedUserArray[i]);
11264            }
11265            pw.println("]");
11266            pw.print("  mUserLru: [");
11267            for (int i=0; i<mUserLru.size(); i++) {
11268                if (i > 0) pw.print(", ");
11269                pw.print(mUserLru.get(i));
11270            }
11271            pw.println("]");
11272            if (dumpAll) {
11273                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11274            }
11275        }
11276        if (mHomeProcess != null && (dumpPackage == null
11277                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11278            if (needSep) {
11279                pw.println();
11280                needSep = false;
11281            }
11282            pw.println("  mHomeProcess: " + mHomeProcess);
11283        }
11284        if (mPreviousProcess != null && (dumpPackage == null
11285                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11286            if (needSep) {
11287                pw.println();
11288                needSep = false;
11289            }
11290            pw.println("  mPreviousProcess: " + mPreviousProcess);
11291        }
11292        if (dumpAll) {
11293            StringBuilder sb = new StringBuilder(128);
11294            sb.append("  mPreviousProcessVisibleTime: ");
11295            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11296            pw.println(sb);
11297        }
11298        if (mHeavyWeightProcess != null && (dumpPackage == null
11299                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11300            if (needSep) {
11301                pw.println();
11302                needSep = false;
11303            }
11304            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11305        }
11306        if (dumpPackage == null) {
11307            pw.println("  mConfiguration: " + mConfiguration);
11308        }
11309        if (dumpAll) {
11310            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11311            if (mCompatModePackages.getPackages().size() > 0) {
11312                boolean printed = false;
11313                for (Map.Entry<String, Integer> entry
11314                        : mCompatModePackages.getPackages().entrySet()) {
11315                    String pkg = entry.getKey();
11316                    int mode = entry.getValue();
11317                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11318                        continue;
11319                    }
11320                    if (!printed) {
11321                        pw.println("  mScreenCompatPackages:");
11322                        printed = true;
11323                    }
11324                    pw.print("    "); pw.print(pkg); pw.print(": ");
11325                            pw.print(mode); pw.println();
11326                }
11327            }
11328        }
11329        if (dumpPackage == null) {
11330            if (mSleeping || mWentToSleep || mLockScreenShown) {
11331                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11332                        + " mLockScreenShown " + mLockScreenShown);
11333            }
11334            if (mShuttingDown || mRunningVoice) {
11335                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11336            }
11337        }
11338        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11339                || mOrigWaitForDebugger) {
11340            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11341                    || dumpPackage.equals(mOrigDebugApp)) {
11342                if (needSep) {
11343                    pw.println();
11344                    needSep = false;
11345                }
11346                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11347                        + " mDebugTransient=" + mDebugTransient
11348                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11349            }
11350        }
11351        if (mOpenGlTraceApp != null) {
11352            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11353                if (needSep) {
11354                    pw.println();
11355                    needSep = false;
11356                }
11357                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11358            }
11359        }
11360        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11361                || mProfileFd != null) {
11362            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11363                if (needSep) {
11364                    pw.println();
11365                    needSep = false;
11366                }
11367                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11368                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11369                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11370                        + mAutoStopProfiler);
11371            }
11372        }
11373        if (dumpPackage == null) {
11374            if (mAlwaysFinishActivities || mController != null) {
11375                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11376                        + " mController=" + mController);
11377            }
11378            if (dumpAll) {
11379                pw.println("  Total persistent processes: " + numPers);
11380                pw.println("  mProcessesReady=" + mProcessesReady
11381                        + " mSystemReady=" + mSystemReady);
11382                pw.println("  mBooting=" + mBooting
11383                        + " mBooted=" + mBooted
11384                        + " mFactoryTest=" + mFactoryTest);
11385                pw.print("  mLastPowerCheckRealtime=");
11386                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11387                        pw.println("");
11388                pw.print("  mLastPowerCheckUptime=");
11389                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11390                        pw.println("");
11391                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11392                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11393                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11394                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11395                        + " (" + mLruProcesses.size() + " total)"
11396                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11397                        + " mNumServiceProcs=" + mNumServiceProcs
11398                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11399                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11400                        + " mLastMemoryLevel" + mLastMemoryLevel
11401                        + " mLastNumProcesses" + mLastNumProcesses);
11402                long now = SystemClock.uptimeMillis();
11403                pw.print("  mLastIdleTime=");
11404                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11405                        pw.print(" mLowRamSinceLastIdle=");
11406                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11407                        pw.println();
11408            }
11409        }
11410
11411        if (!printedAnything) {
11412            pw.println("  (nothing)");
11413        }
11414    }
11415
11416    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11417            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11418        if (mProcessesToGc.size() > 0) {
11419            boolean printed = false;
11420            long now = SystemClock.uptimeMillis();
11421            for (int i=0; i<mProcessesToGc.size(); i++) {
11422                ProcessRecord proc = mProcessesToGc.get(i);
11423                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11424                    continue;
11425                }
11426                if (!printed) {
11427                    if (needSep) pw.println();
11428                    needSep = true;
11429                    pw.println("  Processes that are waiting to GC:");
11430                    printed = true;
11431                }
11432                pw.print("    Process "); pw.println(proc);
11433                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11434                        pw.print(", last gced=");
11435                        pw.print(now-proc.lastRequestedGc);
11436                        pw.print(" ms ago, last lowMem=");
11437                        pw.print(now-proc.lastLowMemory);
11438                        pw.println(" ms ago");
11439
11440            }
11441        }
11442        return needSep;
11443    }
11444
11445    void printOomLevel(PrintWriter pw, String name, int adj) {
11446        pw.print("    ");
11447        if (adj >= 0) {
11448            pw.print(' ');
11449            if (adj < 10) pw.print(' ');
11450        } else {
11451            if (adj > -10) pw.print(' ');
11452        }
11453        pw.print(adj);
11454        pw.print(": ");
11455        pw.print(name);
11456        pw.print(" (");
11457        pw.print(mProcessList.getMemLevel(adj)/1024);
11458        pw.println(" kB)");
11459    }
11460
11461    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11462            int opti, boolean dumpAll) {
11463        boolean needSep = false;
11464
11465        if (mLruProcesses.size() > 0) {
11466            if (needSep) pw.println();
11467            needSep = true;
11468            pw.println("  OOM levels:");
11469            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11470            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11471            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11472            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11473            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11474            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11475            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11476            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11477            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11478            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11479            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11480            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11481            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11482
11483            if (needSep) pw.println();
11484            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11485                    pw.print(" total, non-act at ");
11486                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11487                    pw.print(", non-svc at ");
11488                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11489                    pw.println("):");
11490            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11491            needSep = true;
11492        }
11493
11494        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11495
11496        pw.println();
11497        pw.println("  mHomeProcess: " + mHomeProcess);
11498        pw.println("  mPreviousProcess: " + mPreviousProcess);
11499        if (mHeavyWeightProcess != null) {
11500            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11501        }
11502
11503        return true;
11504    }
11505
11506    /**
11507     * There are three ways to call this:
11508     *  - no provider specified: dump all the providers
11509     *  - a flattened component name that matched an existing provider was specified as the
11510     *    first arg: dump that one provider
11511     *  - the first arg isn't the flattened component name of an existing provider:
11512     *    dump all providers whose component contains the first arg as a substring
11513     */
11514    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11515            int opti, boolean dumpAll) {
11516        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11517    }
11518
11519    static class ItemMatcher {
11520        ArrayList<ComponentName> components;
11521        ArrayList<String> strings;
11522        ArrayList<Integer> objects;
11523        boolean all;
11524
11525        ItemMatcher() {
11526            all = true;
11527        }
11528
11529        void build(String name) {
11530            ComponentName componentName = ComponentName.unflattenFromString(name);
11531            if (componentName != null) {
11532                if (components == null) {
11533                    components = new ArrayList<ComponentName>();
11534                }
11535                components.add(componentName);
11536                all = false;
11537            } else {
11538                int objectId = 0;
11539                // Not a '/' separated full component name; maybe an object ID?
11540                try {
11541                    objectId = Integer.parseInt(name, 16);
11542                    if (objects == null) {
11543                        objects = new ArrayList<Integer>();
11544                    }
11545                    objects.add(objectId);
11546                    all = false;
11547                } catch (RuntimeException e) {
11548                    // Not an integer; just do string match.
11549                    if (strings == null) {
11550                        strings = new ArrayList<String>();
11551                    }
11552                    strings.add(name);
11553                    all = false;
11554                }
11555            }
11556        }
11557
11558        int build(String[] args, int opti) {
11559            for (; opti<args.length; opti++) {
11560                String name = args[opti];
11561                if ("--".equals(name)) {
11562                    return opti+1;
11563                }
11564                build(name);
11565            }
11566            return opti;
11567        }
11568
11569        boolean match(Object object, ComponentName comp) {
11570            if (all) {
11571                return true;
11572            }
11573            if (components != null) {
11574                for (int i=0; i<components.size(); i++) {
11575                    if (components.get(i).equals(comp)) {
11576                        return true;
11577                    }
11578                }
11579            }
11580            if (objects != null) {
11581                for (int i=0; i<objects.size(); i++) {
11582                    if (System.identityHashCode(object) == objects.get(i)) {
11583                        return true;
11584                    }
11585                }
11586            }
11587            if (strings != null) {
11588                String flat = comp.flattenToString();
11589                for (int i=0; i<strings.size(); i++) {
11590                    if (flat.contains(strings.get(i))) {
11591                        return true;
11592                    }
11593                }
11594            }
11595            return false;
11596        }
11597    }
11598
11599    /**
11600     * There are three things that cmd can be:
11601     *  - a flattened component name that matches an existing activity
11602     *  - the cmd arg isn't the flattened component name of an existing activity:
11603     *    dump all activity whose component contains the cmd as a substring
11604     *  - A hex number of the ActivityRecord object instance.
11605     */
11606    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11607            int opti, boolean dumpAll) {
11608        ArrayList<ActivityRecord> activities;
11609
11610        synchronized (this) {
11611            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11612        }
11613
11614        if (activities.size() <= 0) {
11615            return false;
11616        }
11617
11618        String[] newArgs = new String[args.length - opti];
11619        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11620
11621        TaskRecord lastTask = null;
11622        boolean needSep = false;
11623        for (int i=activities.size()-1; i>=0; i--) {
11624            ActivityRecord r = activities.get(i);
11625            if (needSep) {
11626                pw.println();
11627            }
11628            needSep = true;
11629            synchronized (this) {
11630                if (lastTask != r.task) {
11631                    lastTask = r.task;
11632                    pw.print("TASK "); pw.print(lastTask.affinity);
11633                            pw.print(" id="); pw.println(lastTask.taskId);
11634                    if (dumpAll) {
11635                        lastTask.dump(pw, "  ");
11636                    }
11637                }
11638            }
11639            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11640        }
11641        return true;
11642    }
11643
11644    /**
11645     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11646     * there is a thread associated with the activity.
11647     */
11648    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11649            final ActivityRecord r, String[] args, boolean dumpAll) {
11650        String innerPrefix = prefix + "  ";
11651        synchronized (this) {
11652            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11653                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11654                    pw.print(" pid=");
11655                    if (r.app != null) pw.println(r.app.pid);
11656                    else pw.println("(not running)");
11657            if (dumpAll) {
11658                r.dump(pw, innerPrefix);
11659            }
11660        }
11661        if (r.app != null && r.app.thread != null) {
11662            // flush anything that is already in the PrintWriter since the thread is going
11663            // to write to the file descriptor directly
11664            pw.flush();
11665            try {
11666                TransferPipe tp = new TransferPipe();
11667                try {
11668                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11669                            r.appToken, innerPrefix, args);
11670                    tp.go(fd);
11671                } finally {
11672                    tp.kill();
11673                }
11674            } catch (IOException e) {
11675                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11676            } catch (RemoteException e) {
11677                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11678            }
11679        }
11680    }
11681
11682    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11683            int opti, boolean dumpAll, String dumpPackage) {
11684        boolean needSep = false;
11685        boolean onlyHistory = false;
11686        boolean printedAnything = false;
11687
11688        if ("history".equals(dumpPackage)) {
11689            if (opti < args.length && "-s".equals(args[opti])) {
11690                dumpAll = false;
11691            }
11692            onlyHistory = true;
11693            dumpPackage = null;
11694        }
11695
11696        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11697        if (!onlyHistory && dumpAll) {
11698            if (mRegisteredReceivers.size() > 0) {
11699                boolean printed = false;
11700                Iterator it = mRegisteredReceivers.values().iterator();
11701                while (it.hasNext()) {
11702                    ReceiverList r = (ReceiverList)it.next();
11703                    if (dumpPackage != null && (r.app == null ||
11704                            !dumpPackage.equals(r.app.info.packageName))) {
11705                        continue;
11706                    }
11707                    if (!printed) {
11708                        pw.println("  Registered Receivers:");
11709                        needSep = true;
11710                        printed = true;
11711                        printedAnything = true;
11712                    }
11713                    pw.print("  * "); pw.println(r);
11714                    r.dump(pw, "    ");
11715                }
11716            }
11717
11718            if (mReceiverResolver.dump(pw, needSep ?
11719                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11720                    "    ", dumpPackage, false)) {
11721                needSep = true;
11722                printedAnything = true;
11723            }
11724        }
11725
11726        for (BroadcastQueue q : mBroadcastQueues) {
11727            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11728            printedAnything |= needSep;
11729        }
11730
11731        needSep = true;
11732
11733        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11734            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11735                if (needSep) {
11736                    pw.println();
11737                }
11738                needSep = true;
11739                printedAnything = true;
11740                pw.print("  Sticky broadcasts for user ");
11741                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11742                StringBuilder sb = new StringBuilder(128);
11743                for (Map.Entry<String, ArrayList<Intent>> ent
11744                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11745                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11746                    if (dumpAll) {
11747                        pw.println(":");
11748                        ArrayList<Intent> intents = ent.getValue();
11749                        final int N = intents.size();
11750                        for (int i=0; i<N; i++) {
11751                            sb.setLength(0);
11752                            sb.append("    Intent: ");
11753                            intents.get(i).toShortString(sb, false, true, false, false);
11754                            pw.println(sb.toString());
11755                            Bundle bundle = intents.get(i).getExtras();
11756                            if (bundle != null) {
11757                                pw.print("      ");
11758                                pw.println(bundle.toString());
11759                            }
11760                        }
11761                    } else {
11762                        pw.println("");
11763                    }
11764                }
11765            }
11766        }
11767
11768        if (!onlyHistory && dumpAll) {
11769            pw.println();
11770            for (BroadcastQueue queue : mBroadcastQueues) {
11771                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11772                        + queue.mBroadcastsScheduled);
11773            }
11774            pw.println("  mHandler:");
11775            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11776            needSep = true;
11777            printedAnything = true;
11778        }
11779
11780        if (!printedAnything) {
11781            pw.println("  (nothing)");
11782        }
11783    }
11784
11785    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11786            int opti, boolean dumpAll, String dumpPackage) {
11787        boolean needSep;
11788        boolean printedAnything = false;
11789
11790        ItemMatcher matcher = new ItemMatcher();
11791        matcher.build(args, opti);
11792
11793        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11794
11795        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11796        printedAnything |= needSep;
11797
11798        if (mLaunchingProviders.size() > 0) {
11799            boolean printed = false;
11800            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11801                ContentProviderRecord r = mLaunchingProviders.get(i);
11802                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11803                    continue;
11804                }
11805                if (!printed) {
11806                    if (needSep) pw.println();
11807                    needSep = true;
11808                    pw.println("  Launching content providers:");
11809                    printed = true;
11810                    printedAnything = true;
11811                }
11812                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11813                        pw.println(r);
11814            }
11815        }
11816
11817        if (mGrantedUriPermissions.size() > 0) {
11818            boolean printed = false;
11819            int dumpUid = -2;
11820            if (dumpPackage != null) {
11821                try {
11822                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11823                } catch (NameNotFoundException e) {
11824                    dumpUid = -1;
11825                }
11826            }
11827            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11828                int uid = mGrantedUriPermissions.keyAt(i);
11829                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11830                    continue;
11831                }
11832                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11833                if (!printed) {
11834                    if (needSep) pw.println();
11835                    needSep = true;
11836                    pw.println("  Granted Uri Permissions:");
11837                    printed = true;
11838                    printedAnything = true;
11839                }
11840                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11841                for (UriPermission perm : perms.values()) {
11842                    pw.print("    "); pw.println(perm);
11843                    if (dumpAll) {
11844                        perm.dump(pw, "      ");
11845                    }
11846                }
11847            }
11848        }
11849
11850        if (!printedAnything) {
11851            pw.println("  (nothing)");
11852        }
11853    }
11854
11855    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11856            int opti, boolean dumpAll, String dumpPackage) {
11857        boolean printed = false;
11858
11859        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11860
11861        if (mIntentSenderRecords.size() > 0) {
11862            Iterator<WeakReference<PendingIntentRecord>> it
11863                    = mIntentSenderRecords.values().iterator();
11864            while (it.hasNext()) {
11865                WeakReference<PendingIntentRecord> ref = it.next();
11866                PendingIntentRecord rec = ref != null ? ref.get(): null;
11867                if (dumpPackage != null && (rec == null
11868                        || !dumpPackage.equals(rec.key.packageName))) {
11869                    continue;
11870                }
11871                printed = true;
11872                if (rec != null) {
11873                    pw.print("  * "); pw.println(rec);
11874                    if (dumpAll) {
11875                        rec.dump(pw, "    ");
11876                    }
11877                } else {
11878                    pw.print("  * "); pw.println(ref);
11879                }
11880            }
11881        }
11882
11883        if (!printed) {
11884            pw.println("  (nothing)");
11885        }
11886    }
11887
11888    private static final int dumpProcessList(PrintWriter pw,
11889            ActivityManagerService service, List list,
11890            String prefix, String normalLabel, String persistentLabel,
11891            String dumpPackage) {
11892        int numPers = 0;
11893        final int N = list.size()-1;
11894        for (int i=N; i>=0; i--) {
11895            ProcessRecord r = (ProcessRecord)list.get(i);
11896            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11897                continue;
11898            }
11899            pw.println(String.format("%s%s #%2d: %s",
11900                    prefix, (r.persistent ? persistentLabel : normalLabel),
11901                    i, r.toString()));
11902            if (r.persistent) {
11903                numPers++;
11904            }
11905        }
11906        return numPers;
11907    }
11908
11909    private static final boolean dumpProcessOomList(PrintWriter pw,
11910            ActivityManagerService service, List<ProcessRecord> origList,
11911            String prefix, String normalLabel, String persistentLabel,
11912            boolean inclDetails, String dumpPackage) {
11913
11914        ArrayList<Pair<ProcessRecord, Integer>> list
11915                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11916        for (int i=0; i<origList.size(); i++) {
11917            ProcessRecord r = origList.get(i);
11918            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11919                continue;
11920            }
11921            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11922        }
11923
11924        if (list.size() <= 0) {
11925            return false;
11926        }
11927
11928        Comparator<Pair<ProcessRecord, Integer>> comparator
11929                = new Comparator<Pair<ProcessRecord, Integer>>() {
11930            @Override
11931            public int compare(Pair<ProcessRecord, Integer> object1,
11932                    Pair<ProcessRecord, Integer> object2) {
11933                if (object1.first.setAdj != object2.first.setAdj) {
11934                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11935                }
11936                if (object1.second.intValue() != object2.second.intValue()) {
11937                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11938                }
11939                return 0;
11940            }
11941        };
11942
11943        Collections.sort(list, comparator);
11944
11945        final long curRealtime = SystemClock.elapsedRealtime();
11946        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11947        final long curUptime = SystemClock.uptimeMillis();
11948        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11949
11950        for (int i=list.size()-1; i>=0; i--) {
11951            ProcessRecord r = list.get(i).first;
11952            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11953            char schedGroup;
11954            switch (r.setSchedGroup) {
11955                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11956                    schedGroup = 'B';
11957                    break;
11958                case Process.THREAD_GROUP_DEFAULT:
11959                    schedGroup = 'F';
11960                    break;
11961                default:
11962                    schedGroup = '?';
11963                    break;
11964            }
11965            char foreground;
11966            if (r.foregroundActivities) {
11967                foreground = 'A';
11968            } else if (r.foregroundServices) {
11969                foreground = 'S';
11970            } else {
11971                foreground = ' ';
11972            }
11973            String procState = ProcessList.makeProcStateString(r.curProcState);
11974            pw.print(prefix);
11975            pw.print(r.persistent ? persistentLabel : normalLabel);
11976            pw.print(" #");
11977            int num = (origList.size()-1)-list.get(i).second;
11978            if (num < 10) pw.print(' ');
11979            pw.print(num);
11980            pw.print(": ");
11981            pw.print(oomAdj);
11982            pw.print(' ');
11983            pw.print(schedGroup);
11984            pw.print('/');
11985            pw.print(foreground);
11986            pw.print('/');
11987            pw.print(procState);
11988            pw.print(" trm:");
11989            if (r.trimMemoryLevel < 10) pw.print(' ');
11990            pw.print(r.trimMemoryLevel);
11991            pw.print(' ');
11992            pw.print(r.toShortString());
11993            pw.print(" (");
11994            pw.print(r.adjType);
11995            pw.println(')');
11996            if (r.adjSource != null || r.adjTarget != null) {
11997                pw.print(prefix);
11998                pw.print("    ");
11999                if (r.adjTarget instanceof ComponentName) {
12000                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12001                } else if (r.adjTarget != null) {
12002                    pw.print(r.adjTarget.toString());
12003                } else {
12004                    pw.print("{null}");
12005                }
12006                pw.print("<=");
12007                if (r.adjSource instanceof ProcessRecord) {
12008                    pw.print("Proc{");
12009                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12010                    pw.println("}");
12011                } else if (r.adjSource != null) {
12012                    pw.println(r.adjSource.toString());
12013                } else {
12014                    pw.println("{null}");
12015                }
12016            }
12017            if (inclDetails) {
12018                pw.print(prefix);
12019                pw.print("    ");
12020                pw.print("oom: max="); pw.print(r.maxAdj);
12021                pw.print(" curRaw="); pw.print(r.curRawAdj);
12022                pw.print(" setRaw="); pw.print(r.setRawAdj);
12023                pw.print(" cur="); pw.print(r.curAdj);
12024                pw.print(" set="); pw.println(r.setAdj);
12025                pw.print(prefix);
12026                pw.print("    ");
12027                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12028                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12029                pw.print(" lastPss="); pw.print(r.lastPss);
12030                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12031                pw.print(prefix);
12032                pw.print("    ");
12033                pw.print("keeping="); pw.print(r.keeping);
12034                pw.print(" cached="); pw.print(r.cached);
12035                pw.print(" empty="); pw.print(r.empty);
12036                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12037
12038                if (!r.keeping) {
12039                    if (r.lastWakeTime != 0) {
12040                        long wtime;
12041                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12042                        synchronized (stats) {
12043                            wtime = stats.getProcessWakeTime(r.info.uid,
12044                                    r.pid, curRealtime);
12045                        }
12046                        long timeUsed = wtime - r.lastWakeTime;
12047                        pw.print(prefix);
12048                        pw.print("    ");
12049                        pw.print("keep awake over ");
12050                        TimeUtils.formatDuration(realtimeSince, pw);
12051                        pw.print(" used ");
12052                        TimeUtils.formatDuration(timeUsed, pw);
12053                        pw.print(" (");
12054                        pw.print((timeUsed*100)/realtimeSince);
12055                        pw.println("%)");
12056                    }
12057                    if (r.lastCpuTime != 0) {
12058                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12059                        pw.print(prefix);
12060                        pw.print("    ");
12061                        pw.print("run cpu over ");
12062                        TimeUtils.formatDuration(uptimeSince, pw);
12063                        pw.print(" used ");
12064                        TimeUtils.formatDuration(timeUsed, pw);
12065                        pw.print(" (");
12066                        pw.print((timeUsed*100)/uptimeSince);
12067                        pw.println("%)");
12068                    }
12069                }
12070            }
12071        }
12072        return true;
12073    }
12074
12075    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12076        ArrayList<ProcessRecord> procs;
12077        synchronized (this) {
12078            if (args != null && args.length > start
12079                    && args[start].charAt(0) != '-') {
12080                procs = new ArrayList<ProcessRecord>();
12081                int pid = -1;
12082                try {
12083                    pid = Integer.parseInt(args[start]);
12084                } catch (NumberFormatException e) {
12085                }
12086                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12087                    ProcessRecord proc = mLruProcesses.get(i);
12088                    if (proc.pid == pid) {
12089                        procs.add(proc);
12090                    } else if (proc.processName.equals(args[start])) {
12091                        procs.add(proc);
12092                    }
12093                }
12094                if (procs.size() <= 0) {
12095                    return null;
12096                }
12097            } else {
12098                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12099            }
12100        }
12101        return procs;
12102    }
12103
12104    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12105            PrintWriter pw, String[] args) {
12106        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12107        if (procs == null) {
12108            pw.println("No process found for: " + args[0]);
12109            return;
12110        }
12111
12112        long uptime = SystemClock.uptimeMillis();
12113        long realtime = SystemClock.elapsedRealtime();
12114        pw.println("Applications Graphics Acceleration Info:");
12115        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12116
12117        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12118            ProcessRecord r = procs.get(i);
12119            if (r.thread != null) {
12120                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12121                pw.flush();
12122                try {
12123                    TransferPipe tp = new TransferPipe();
12124                    try {
12125                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12126                        tp.go(fd);
12127                    } finally {
12128                        tp.kill();
12129                    }
12130                } catch (IOException e) {
12131                    pw.println("Failure while dumping the app: " + r);
12132                    pw.flush();
12133                } catch (RemoteException e) {
12134                    pw.println("Got a RemoteException while dumping the app " + r);
12135                    pw.flush();
12136                }
12137            }
12138        }
12139    }
12140
12141    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12142        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12143        if (procs == null) {
12144            pw.println("No process found for: " + args[0]);
12145            return;
12146        }
12147
12148        pw.println("Applications Database Info:");
12149
12150        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12151            ProcessRecord r = procs.get(i);
12152            if (r.thread != null) {
12153                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12154                pw.flush();
12155                try {
12156                    TransferPipe tp = new TransferPipe();
12157                    try {
12158                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12159                        tp.go(fd);
12160                    } finally {
12161                        tp.kill();
12162                    }
12163                } catch (IOException e) {
12164                    pw.println("Failure while dumping the app: " + r);
12165                    pw.flush();
12166                } catch (RemoteException e) {
12167                    pw.println("Got a RemoteException while dumping the app " + r);
12168                    pw.flush();
12169                }
12170            }
12171        }
12172    }
12173
12174    final static class MemItem {
12175        final boolean isProc;
12176        final String label;
12177        final String shortLabel;
12178        final long pss;
12179        final int id;
12180        final boolean hasActivities;
12181        ArrayList<MemItem> subitems;
12182
12183        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12184                boolean _hasActivities) {
12185            isProc = true;
12186            label = _label;
12187            shortLabel = _shortLabel;
12188            pss = _pss;
12189            id = _id;
12190            hasActivities = _hasActivities;
12191        }
12192
12193        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12194            isProc = false;
12195            label = _label;
12196            shortLabel = _shortLabel;
12197            pss = _pss;
12198            id = _id;
12199            hasActivities = false;
12200        }
12201    }
12202
12203    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12204            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12205        if (sort && !isCompact) {
12206            Collections.sort(items, new Comparator<MemItem>() {
12207                @Override
12208                public int compare(MemItem lhs, MemItem rhs) {
12209                    if (lhs.pss < rhs.pss) {
12210                        return 1;
12211                    } else if (lhs.pss > rhs.pss) {
12212                        return -1;
12213                    }
12214                    return 0;
12215                }
12216            });
12217        }
12218
12219        for (int i=0; i<items.size(); i++) {
12220            MemItem mi = items.get(i);
12221            if (!isCompact) {
12222                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12223            } else if (mi.isProc) {
12224                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12225                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12226                pw.println(mi.hasActivities ? ",a" : ",e");
12227            } else {
12228                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12229                pw.println(mi.pss);
12230            }
12231            if (mi.subitems != null) {
12232                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12233                        true, isCompact);
12234            }
12235        }
12236    }
12237
12238    // These are in KB.
12239    static final long[] DUMP_MEM_BUCKETS = new long[] {
12240        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12241        120*1024, 160*1024, 200*1024,
12242        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12243        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12244    };
12245
12246    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12247            boolean stackLike) {
12248        int start = label.lastIndexOf('.');
12249        if (start >= 0) start++;
12250        else start = 0;
12251        int end = label.length();
12252        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12253            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12254                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12255                out.append(bucket);
12256                out.append(stackLike ? "MB." : "MB ");
12257                out.append(label, start, end);
12258                return;
12259            }
12260        }
12261        out.append(memKB/1024);
12262        out.append(stackLike ? "MB." : "MB ");
12263        out.append(label, start, end);
12264    }
12265
12266    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12267            ProcessList.NATIVE_ADJ,
12268            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12269            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12270            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12271            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12272            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12273    };
12274    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12275            "Native",
12276            "System", "Persistent", "Foreground",
12277            "Visible", "Perceptible",
12278            "Heavy Weight", "Backup",
12279            "A Services", "Home",
12280            "Previous", "B Services", "Cached"
12281    };
12282    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12283            "native",
12284            "sys", "pers", "fore",
12285            "vis", "percept",
12286            "heavy", "backup",
12287            "servicea", "home",
12288            "prev", "serviceb", "cached"
12289    };
12290
12291    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12292            long realtime, boolean isCheckinRequest, boolean isCompact) {
12293        if (isCheckinRequest || isCompact) {
12294            // short checkin version
12295            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12296        } else {
12297            pw.println("Applications Memory Usage (kB):");
12298            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12299        }
12300    }
12301
12302    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12303            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12304        boolean dumpDetails = false;
12305        boolean dumpFullDetails = false;
12306        boolean dumpDalvik = false;
12307        boolean oomOnly = false;
12308        boolean isCompact = false;
12309        boolean localOnly = false;
12310
12311        int opti = 0;
12312        while (opti < args.length) {
12313            String opt = args[opti];
12314            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12315                break;
12316            }
12317            opti++;
12318            if ("-a".equals(opt)) {
12319                dumpDetails = true;
12320                dumpFullDetails = true;
12321                dumpDalvik = true;
12322            } else if ("-d".equals(opt)) {
12323                dumpDalvik = true;
12324            } else if ("-c".equals(opt)) {
12325                isCompact = true;
12326            } else if ("--oom".equals(opt)) {
12327                oomOnly = true;
12328            } else if ("--local".equals(opt)) {
12329                localOnly = true;
12330            } else if ("-h".equals(opt)) {
12331                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12332                pw.println("  -a: include all available information for each process.");
12333                pw.println("  -d: include dalvik details when dumping process details.");
12334                pw.println("  -c: dump in a compact machine-parseable representation.");
12335                pw.println("  --oom: only show processes organized by oom adj.");
12336                pw.println("  --local: only collect details locally, don't call process.");
12337                pw.println("If [process] is specified it can be the name or ");
12338                pw.println("pid of a specific process to dump.");
12339                return;
12340            } else {
12341                pw.println("Unknown argument: " + opt + "; use -h for help");
12342            }
12343        }
12344
12345        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12346        long uptime = SystemClock.uptimeMillis();
12347        long realtime = SystemClock.elapsedRealtime();
12348        final long[] tmpLong = new long[1];
12349
12350        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12351        if (procs == null) {
12352            // No Java processes.  Maybe they want to print a native process.
12353            if (args != null && args.length > opti
12354                    && args[opti].charAt(0) != '-') {
12355                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12356                        = new ArrayList<ProcessCpuTracker.Stats>();
12357                updateCpuStatsNow();
12358                int findPid = -1;
12359                try {
12360                    findPid = Integer.parseInt(args[opti]);
12361                } catch (NumberFormatException e) {
12362                }
12363                synchronized (mProcessCpuThread) {
12364                    final int N = mProcessCpuTracker.countStats();
12365                    for (int i=0; i<N; i++) {
12366                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12367                        if (st.pid == findPid || (st.baseName != null
12368                                && st.baseName.equals(args[opti]))) {
12369                            nativeProcs.add(st);
12370                        }
12371                    }
12372                }
12373                if (nativeProcs.size() > 0) {
12374                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12375                            isCompact);
12376                    Debug.MemoryInfo mi = null;
12377                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12378                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12379                        final int pid = r.pid;
12380                        if (!isCheckinRequest && dumpDetails) {
12381                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12382                        }
12383                        if (mi == null) {
12384                            mi = new Debug.MemoryInfo();
12385                        }
12386                        if (dumpDetails || (!brief && !oomOnly)) {
12387                            Debug.getMemoryInfo(pid, mi);
12388                        } else {
12389                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12390                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12391                        }
12392                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12393                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12394                        if (isCheckinRequest) {
12395                            pw.println();
12396                        }
12397                    }
12398                    return;
12399                }
12400            }
12401            pw.println("No process found for: " + args[opti]);
12402            return;
12403        }
12404
12405        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12406            dumpDetails = true;
12407        }
12408
12409        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12410
12411        String[] innerArgs = new String[args.length-opti];
12412        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12413
12414        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12415        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12416        long nativePss=0, dalvikPss=0, otherPss=0;
12417        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12418
12419        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12420        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12421                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12422
12423        long totalPss = 0;
12424        long cachedPss = 0;
12425
12426        Debug.MemoryInfo mi = null;
12427        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12428            final ProcessRecord r = procs.get(i);
12429            final IApplicationThread thread;
12430            final int pid;
12431            final int oomAdj;
12432            final boolean hasActivities;
12433            synchronized (this) {
12434                thread = r.thread;
12435                pid = r.pid;
12436                oomAdj = r.getSetAdjWithServices();
12437                hasActivities = r.activities.size() > 0;
12438            }
12439            if (thread != null) {
12440                if (!isCheckinRequest && dumpDetails) {
12441                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12442                }
12443                if (mi == null) {
12444                    mi = new Debug.MemoryInfo();
12445                }
12446                if (dumpDetails || (!brief && !oomOnly)) {
12447                    Debug.getMemoryInfo(pid, mi);
12448                } else {
12449                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12450                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12451                }
12452                if (dumpDetails) {
12453                    if (localOnly) {
12454                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12455                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12456                        if (isCheckinRequest) {
12457                            pw.println();
12458                        }
12459                    } else {
12460                        try {
12461                            pw.flush();
12462                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12463                                    dumpDalvik, innerArgs);
12464                        } catch (RemoteException e) {
12465                            if (!isCheckinRequest) {
12466                                pw.println("Got RemoteException!");
12467                                pw.flush();
12468                            }
12469                        }
12470                    }
12471                }
12472
12473                final long myTotalPss = mi.getTotalPss();
12474                final long myTotalUss = mi.getTotalUss();
12475
12476                synchronized (this) {
12477                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12478                        // Record this for posterity if the process has been stable.
12479                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12480                    }
12481                }
12482
12483                if (!isCheckinRequest && mi != null) {
12484                    totalPss += myTotalPss;
12485                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12486                            (hasActivities ? " / activities)" : ")"),
12487                            r.processName, myTotalPss, pid, hasActivities);
12488                    procMems.add(pssItem);
12489                    procMemsMap.put(pid, pssItem);
12490
12491                    nativePss += mi.nativePss;
12492                    dalvikPss += mi.dalvikPss;
12493                    otherPss += mi.otherPss;
12494                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12495                        long mem = mi.getOtherPss(j);
12496                        miscPss[j] += mem;
12497                        otherPss -= mem;
12498                    }
12499
12500                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12501                        cachedPss += myTotalPss;
12502                    }
12503
12504                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12505                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12506                                || oomIndex == (oomPss.length-1)) {
12507                            oomPss[oomIndex] += myTotalPss;
12508                            if (oomProcs[oomIndex] == null) {
12509                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12510                            }
12511                            oomProcs[oomIndex].add(pssItem);
12512                            break;
12513                        }
12514                    }
12515                }
12516            }
12517        }
12518
12519        if (!isCheckinRequest && procs.size() > 1) {
12520            // If we are showing aggregations, also look for native processes to
12521            // include so that our aggregations are more accurate.
12522            updateCpuStatsNow();
12523            synchronized (mProcessCpuThread) {
12524                final int N = mProcessCpuTracker.countStats();
12525                for (int i=0; i<N; i++) {
12526                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12527                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12528                        if (mi == null) {
12529                            mi = new Debug.MemoryInfo();
12530                        }
12531                        if (!brief && !oomOnly) {
12532                            Debug.getMemoryInfo(st.pid, mi);
12533                        } else {
12534                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12535                            mi.nativePrivateDirty = (int)tmpLong[0];
12536                        }
12537
12538                        final long myTotalPss = mi.getTotalPss();
12539                        totalPss += myTotalPss;
12540
12541                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12542                                st.name, myTotalPss, st.pid, false);
12543                        procMems.add(pssItem);
12544
12545                        nativePss += mi.nativePss;
12546                        dalvikPss += mi.dalvikPss;
12547                        otherPss += mi.otherPss;
12548                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12549                            long mem = mi.getOtherPss(j);
12550                            miscPss[j] += mem;
12551                            otherPss -= mem;
12552                        }
12553                        oomPss[0] += myTotalPss;
12554                        if (oomProcs[0] == null) {
12555                            oomProcs[0] = new ArrayList<MemItem>();
12556                        }
12557                        oomProcs[0].add(pssItem);
12558                    }
12559                }
12560            }
12561
12562            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12563
12564            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12565            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12566            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12567            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12568                String label = Debug.MemoryInfo.getOtherLabel(j);
12569                catMems.add(new MemItem(label, label, miscPss[j], j));
12570            }
12571
12572            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12573            for (int j=0; j<oomPss.length; j++) {
12574                if (oomPss[j] != 0) {
12575                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12576                            : DUMP_MEM_OOM_LABEL[j];
12577                    MemItem item = new MemItem(label, label, oomPss[j],
12578                            DUMP_MEM_OOM_ADJ[j]);
12579                    item.subitems = oomProcs[j];
12580                    oomMems.add(item);
12581                }
12582            }
12583
12584            if (!brief && !oomOnly && !isCompact) {
12585                pw.println();
12586                pw.println("Total PSS by process:");
12587                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12588                pw.println();
12589            }
12590            if (!isCompact) {
12591                pw.println("Total PSS by OOM adjustment:");
12592            }
12593            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12594            if (!brief && !oomOnly) {
12595                PrintWriter out = categoryPw != null ? categoryPw : pw;
12596                if (!isCompact) {
12597                    out.println();
12598                    out.println("Total PSS by category:");
12599                }
12600                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12601            }
12602            if (!isCompact) {
12603                pw.println();
12604            }
12605            MemInfoReader memInfo = new MemInfoReader();
12606            memInfo.readMemInfo();
12607            if (!brief) {
12608                if (!isCompact) {
12609                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12610                    pw.print(" kB (status ");
12611                    switch (mLastMemoryLevel) {
12612                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12613                            pw.println("normal)");
12614                            break;
12615                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12616                            pw.println("moderate)");
12617                            break;
12618                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12619                            pw.println("low)");
12620                            break;
12621                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12622                            pw.println("critical)");
12623                            break;
12624                        default:
12625                            pw.print(mLastMemoryLevel);
12626                            pw.println(")");
12627                            break;
12628                    }
12629                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12630                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12631                            pw.print(cachedPss); pw.print(" cached pss + ");
12632                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12633                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12634                } else {
12635                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12636                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12637                            + memInfo.getFreeSizeKb()); pw.print(",");
12638                    pw.println(totalPss - cachedPss);
12639                }
12640            }
12641            if (!isCompact) {
12642                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12643                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12644                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12645                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12646                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12647                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12648                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12649                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12650                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12651                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12652                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12653            }
12654            if (!brief) {
12655                if (memInfo.getZramTotalSizeKb() != 0) {
12656                    if (!isCompact) {
12657                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12658                                pw.print(" kB physical used for ");
12659                                pw.print(memInfo.getSwapTotalSizeKb()
12660                                        - memInfo.getSwapFreeSizeKb());
12661                                pw.print(" kB in swap (");
12662                                pw.print(memInfo.getSwapTotalSizeKb());
12663                                pw.println(" kB total swap)");
12664                    } else {
12665                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12666                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12667                                pw.println(memInfo.getSwapFreeSizeKb());
12668                    }
12669                }
12670                final int[] SINGLE_LONG_FORMAT = new int[] {
12671                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12672                };
12673                long[] longOut = new long[1];
12674                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12675                        SINGLE_LONG_FORMAT, null, longOut, null);
12676                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12677                longOut[0] = 0;
12678                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12679                        SINGLE_LONG_FORMAT, null, longOut, null);
12680                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12681                longOut[0] = 0;
12682                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12683                        SINGLE_LONG_FORMAT, null, longOut, null);
12684                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12685                longOut[0] = 0;
12686                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12687                        SINGLE_LONG_FORMAT, null, longOut, null);
12688                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12689                if (!isCompact) {
12690                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12691                        pw.print("      KSM: "); pw.print(sharing);
12692                                pw.print(" kB saved from shared ");
12693                                pw.print(shared); pw.println(" kB");
12694                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12695                                pw.print(voltile); pw.println(" kB volatile");
12696                    }
12697                    pw.print("   Tuning: ");
12698                    pw.print(ActivityManager.staticGetMemoryClass());
12699                    pw.print(" (large ");
12700                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12701                    pw.print("), oom ");
12702                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12703                    pw.print(" kB");
12704                    pw.print(", restore limit ");
12705                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12706                    pw.print(" kB");
12707                    if (ActivityManager.isLowRamDeviceStatic()) {
12708                        pw.print(" (low-ram)");
12709                    }
12710                    if (ActivityManager.isHighEndGfx()) {
12711                        pw.print(" (high-end-gfx)");
12712                    }
12713                    pw.println();
12714                } else {
12715                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12716                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12717                    pw.println(voltile);
12718                    pw.print("tuning,");
12719                    pw.print(ActivityManager.staticGetMemoryClass());
12720                    pw.print(',');
12721                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12722                    pw.print(',');
12723                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12724                    if (ActivityManager.isLowRamDeviceStatic()) {
12725                        pw.print(",low-ram");
12726                    }
12727                    if (ActivityManager.isHighEndGfx()) {
12728                        pw.print(",high-end-gfx");
12729                    }
12730                    pw.println();
12731                }
12732            }
12733        }
12734    }
12735
12736    /**
12737     * Searches array of arguments for the specified string
12738     * @param args array of argument strings
12739     * @param value value to search for
12740     * @return true if the value is contained in the array
12741     */
12742    private static boolean scanArgs(String[] args, String value) {
12743        if (args != null) {
12744            for (String arg : args) {
12745                if (value.equals(arg)) {
12746                    return true;
12747                }
12748            }
12749        }
12750        return false;
12751    }
12752
12753    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12754            ContentProviderRecord cpr, boolean always) {
12755        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12756
12757        if (!inLaunching || always) {
12758            synchronized (cpr) {
12759                cpr.launchingApp = null;
12760                cpr.notifyAll();
12761            }
12762            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12763            String names[] = cpr.info.authority.split(";");
12764            for (int j = 0; j < names.length; j++) {
12765                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12766            }
12767        }
12768
12769        for (int i=0; i<cpr.connections.size(); i++) {
12770            ContentProviderConnection conn = cpr.connections.get(i);
12771            if (conn.waiting) {
12772                // If this connection is waiting for the provider, then we don't
12773                // need to mess with its process unless we are always removing
12774                // or for some reason the provider is not currently launching.
12775                if (inLaunching && !always) {
12776                    continue;
12777                }
12778            }
12779            ProcessRecord capp = conn.client;
12780            conn.dead = true;
12781            if (conn.stableCount > 0) {
12782                if (!capp.persistent && capp.thread != null
12783                        && capp.pid != 0
12784                        && capp.pid != MY_PID) {
12785                    killUnneededProcessLocked(capp, "depends on provider "
12786                            + cpr.name.flattenToShortString()
12787                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12788                }
12789            } else if (capp.thread != null && conn.provider.provider != null) {
12790                try {
12791                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12792                } catch (RemoteException e) {
12793                }
12794                // In the protocol here, we don't expect the client to correctly
12795                // clean up this connection, we'll just remove it.
12796                cpr.connections.remove(i);
12797                conn.client.conProviders.remove(conn);
12798            }
12799        }
12800
12801        if (inLaunching && always) {
12802            mLaunchingProviders.remove(cpr);
12803        }
12804        return inLaunching;
12805    }
12806
12807    /**
12808     * Main code for cleaning up a process when it has gone away.  This is
12809     * called both as a result of the process dying, or directly when stopping
12810     * a process when running in single process mode.
12811     */
12812    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12813            boolean restarting, boolean allowRestart, int index) {
12814        if (index >= 0) {
12815            removeLruProcessLocked(app);
12816            ProcessList.remove(app.pid);
12817        }
12818
12819        mProcessesToGc.remove(app);
12820        mPendingPssProcesses.remove(app);
12821
12822        // Dismiss any open dialogs.
12823        if (app.crashDialog != null && !app.forceCrashReport) {
12824            app.crashDialog.dismiss();
12825            app.crashDialog = null;
12826        }
12827        if (app.anrDialog != null) {
12828            app.anrDialog.dismiss();
12829            app.anrDialog = null;
12830        }
12831        if (app.waitDialog != null) {
12832            app.waitDialog.dismiss();
12833            app.waitDialog = null;
12834        }
12835
12836        app.crashing = false;
12837        app.notResponding = false;
12838
12839        app.resetPackageList(mProcessStats);
12840        app.unlinkDeathRecipient();
12841        app.makeInactive(mProcessStats);
12842        app.forcingToForeground = null;
12843        updateProcessForegroundLocked(app, false, false);
12844        app.foregroundActivities = false;
12845        app.hasShownUi = false;
12846        app.treatLikeActivity = false;
12847        app.hasAboveClient = false;
12848        app.hasClientActivities = false;
12849
12850        mServices.killServicesLocked(app, allowRestart);
12851
12852        boolean restart = false;
12853
12854        // Remove published content providers.
12855        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12856            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12857            final boolean always = app.bad || !allowRestart;
12858            if (removeDyingProviderLocked(app, cpr, always) || always) {
12859                // We left the provider in the launching list, need to
12860                // restart it.
12861                restart = true;
12862            }
12863
12864            cpr.provider = null;
12865            cpr.proc = null;
12866        }
12867        app.pubProviders.clear();
12868
12869        // Take care of any launching providers waiting for this process.
12870        if (checkAppInLaunchingProvidersLocked(app, false)) {
12871            restart = true;
12872        }
12873
12874        // Unregister from connected content providers.
12875        if (!app.conProviders.isEmpty()) {
12876            for (int i=0; i<app.conProviders.size(); i++) {
12877                ContentProviderConnection conn = app.conProviders.get(i);
12878                conn.provider.connections.remove(conn);
12879            }
12880            app.conProviders.clear();
12881        }
12882
12883        // At this point there may be remaining entries in mLaunchingProviders
12884        // where we were the only one waiting, so they are no longer of use.
12885        // Look for these and clean up if found.
12886        // XXX Commented out for now.  Trying to figure out a way to reproduce
12887        // the actual situation to identify what is actually going on.
12888        if (false) {
12889            for (int i=0; i<mLaunchingProviders.size(); i++) {
12890                ContentProviderRecord cpr = (ContentProviderRecord)
12891                        mLaunchingProviders.get(i);
12892                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12893                    synchronized (cpr) {
12894                        cpr.launchingApp = null;
12895                        cpr.notifyAll();
12896                    }
12897                }
12898            }
12899        }
12900
12901        skipCurrentReceiverLocked(app);
12902
12903        // Unregister any receivers.
12904        for (int i=app.receivers.size()-1; i>=0; i--) {
12905            removeReceiverLocked(app.receivers.valueAt(i));
12906        }
12907        app.receivers.clear();
12908
12909        // If the app is undergoing backup, tell the backup manager about it
12910        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12911            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12912                    + mBackupTarget.appInfo + " died during backup");
12913            try {
12914                IBackupManager bm = IBackupManager.Stub.asInterface(
12915                        ServiceManager.getService(Context.BACKUP_SERVICE));
12916                bm.agentDisconnected(app.info.packageName);
12917            } catch (RemoteException e) {
12918                // can't happen; backup manager is local
12919            }
12920        }
12921
12922        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12923            ProcessChangeItem item = mPendingProcessChanges.get(i);
12924            if (item.pid == app.pid) {
12925                mPendingProcessChanges.remove(i);
12926                mAvailProcessChanges.add(item);
12927            }
12928        }
12929        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12930
12931        // If the caller is restarting this app, then leave it in its
12932        // current lists and let the caller take care of it.
12933        if (restarting) {
12934            return;
12935        }
12936
12937        if (!app.persistent || app.isolated) {
12938            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12939                    "Removing non-persistent process during cleanup: " + app);
12940            mProcessNames.remove(app.processName, app.uid);
12941            mIsolatedProcesses.remove(app.uid);
12942            if (mHeavyWeightProcess == app) {
12943                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12944                        mHeavyWeightProcess.userId, 0));
12945                mHeavyWeightProcess = null;
12946            }
12947        } else if (!app.removed) {
12948            // This app is persistent, so we need to keep its record around.
12949            // If it is not already on the pending app list, add it there
12950            // and start a new process for it.
12951            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12952                mPersistentStartingProcesses.add(app);
12953                restart = true;
12954            }
12955        }
12956        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12957                "Clean-up removing on hold: " + app);
12958        mProcessesOnHold.remove(app);
12959
12960        if (app == mHomeProcess) {
12961            mHomeProcess = null;
12962        }
12963        if (app == mPreviousProcess) {
12964            mPreviousProcess = null;
12965        }
12966
12967        if (restart && !app.isolated) {
12968            // We have components that still need to be running in the
12969            // process, so re-launch it.
12970            mProcessNames.put(app.processName, app.uid, app);
12971            startProcessLocked(app, "restart", app.processName);
12972        } else if (app.pid > 0 && app.pid != MY_PID) {
12973            // Goodbye!
12974            boolean removed;
12975            synchronized (mPidsSelfLocked) {
12976                mPidsSelfLocked.remove(app.pid);
12977                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12978            }
12979            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12980                    app.processName, app.info.uid);
12981            if (app.isolated) {
12982                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12983            }
12984            app.setPid(0);
12985        }
12986    }
12987
12988    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12989        // Look through the content providers we are waiting to have launched,
12990        // and if any run in this process then either schedule a restart of
12991        // the process or kill the client waiting for it if this process has
12992        // gone bad.
12993        int NL = mLaunchingProviders.size();
12994        boolean restart = false;
12995        for (int i=0; i<NL; i++) {
12996            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12997            if (cpr.launchingApp == app) {
12998                if (!alwaysBad && !app.bad) {
12999                    restart = true;
13000                } else {
13001                    removeDyingProviderLocked(app, cpr, true);
13002                    // cpr should have been removed from mLaunchingProviders
13003                    NL = mLaunchingProviders.size();
13004                    i--;
13005                }
13006            }
13007        }
13008        return restart;
13009    }
13010
13011    // =========================================================
13012    // SERVICES
13013    // =========================================================
13014
13015    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13016            int flags) {
13017        enforceNotIsolatedCaller("getServices");
13018        synchronized (this) {
13019            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13020        }
13021    }
13022
13023    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13024        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13025        synchronized (this) {
13026            return mServices.getRunningServiceControlPanelLocked(name);
13027        }
13028    }
13029
13030    public ComponentName startService(IApplicationThread caller, Intent service,
13031            String resolvedType, int userId) {
13032        enforceNotIsolatedCaller("startService");
13033        // Refuse possible leaked file descriptors
13034        if (service != null && service.hasFileDescriptors() == true) {
13035            throw new IllegalArgumentException("File descriptors passed in Intent");
13036        }
13037
13038        if (DEBUG_SERVICE)
13039            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13040        synchronized(this) {
13041            final int callingPid = Binder.getCallingPid();
13042            final int callingUid = Binder.getCallingUid();
13043            final long origId = Binder.clearCallingIdentity();
13044            ComponentName res = mServices.startServiceLocked(caller, service,
13045                    resolvedType, callingPid, callingUid, userId);
13046            Binder.restoreCallingIdentity(origId);
13047            return res;
13048        }
13049    }
13050
13051    ComponentName startServiceInPackage(int uid,
13052            Intent service, String resolvedType, int userId) {
13053        synchronized(this) {
13054            if (DEBUG_SERVICE)
13055                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13056            final long origId = Binder.clearCallingIdentity();
13057            ComponentName res = mServices.startServiceLocked(null, service,
13058                    resolvedType, -1, uid, userId);
13059            Binder.restoreCallingIdentity(origId);
13060            return res;
13061        }
13062    }
13063
13064    public int stopService(IApplicationThread caller, Intent service,
13065            String resolvedType, int userId) {
13066        enforceNotIsolatedCaller("stopService");
13067        // Refuse possible leaked file descriptors
13068        if (service != null && service.hasFileDescriptors() == true) {
13069            throw new IllegalArgumentException("File descriptors passed in Intent");
13070        }
13071
13072        synchronized(this) {
13073            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13074        }
13075    }
13076
13077    public IBinder peekService(Intent service, String resolvedType) {
13078        enforceNotIsolatedCaller("peekService");
13079        // Refuse possible leaked file descriptors
13080        if (service != null && service.hasFileDescriptors() == true) {
13081            throw new IllegalArgumentException("File descriptors passed in Intent");
13082        }
13083        synchronized(this) {
13084            return mServices.peekServiceLocked(service, resolvedType);
13085        }
13086    }
13087
13088    public boolean stopServiceToken(ComponentName className, IBinder token,
13089            int startId) {
13090        synchronized(this) {
13091            return mServices.stopServiceTokenLocked(className, token, startId);
13092        }
13093    }
13094
13095    public void setServiceForeground(ComponentName className, IBinder token,
13096            int id, Notification notification, boolean removeNotification) {
13097        synchronized(this) {
13098            mServices.setServiceForegroundLocked(className, token, id, notification,
13099                    removeNotification);
13100        }
13101    }
13102
13103    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13104            boolean requireFull, String name, String callerPackage) {
13105        final int callingUserId = UserHandle.getUserId(callingUid);
13106        if (callingUserId != userId) {
13107            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13108                if ((requireFull || checkComponentPermission(
13109                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13110                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13111                        && checkComponentPermission(
13112                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13113                                callingPid, callingUid, -1, true)
13114                                != PackageManager.PERMISSION_GRANTED) {
13115                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13116                        // In this case, they would like to just execute as their
13117                        // owner user instead of failing.
13118                        userId = callingUserId;
13119                    } else {
13120                        StringBuilder builder = new StringBuilder(128);
13121                        builder.append("Permission Denial: ");
13122                        builder.append(name);
13123                        if (callerPackage != null) {
13124                            builder.append(" from ");
13125                            builder.append(callerPackage);
13126                        }
13127                        builder.append(" asks to run as user ");
13128                        builder.append(userId);
13129                        builder.append(" but is calling from user ");
13130                        builder.append(UserHandle.getUserId(callingUid));
13131                        builder.append("; this requires ");
13132                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13133                        if (!requireFull) {
13134                            builder.append(" or ");
13135                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13136                        }
13137                        String msg = builder.toString();
13138                        Slog.w(TAG, msg);
13139                        throw new SecurityException(msg);
13140                    }
13141                }
13142            }
13143            if (userId == UserHandle.USER_CURRENT
13144                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13145                // Note that we may be accessing this outside of a lock...
13146                // shouldn't be a big deal, if this is being called outside
13147                // of a locked context there is intrinsically a race with
13148                // the value the caller will receive and someone else changing it.
13149                userId = mCurrentUserId;
13150            }
13151            if (!allowAll && userId < 0) {
13152                throw new IllegalArgumentException(
13153                        "Call does not support special user #" + userId);
13154            }
13155        }
13156        return userId;
13157    }
13158
13159    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13160            String className, int flags) {
13161        boolean result = false;
13162        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13163            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13164                if (ActivityManager.checkUidPermission(
13165                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13166                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13167                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13168                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13169                            + " requests FLAG_SINGLE_USER, but app does not hold "
13170                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13171                    Slog.w(TAG, msg);
13172                    throw new SecurityException(msg);
13173                }
13174                result = true;
13175            }
13176        } else if (componentProcessName == aInfo.packageName) {
13177            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13178        } else if ("system".equals(componentProcessName)) {
13179            result = true;
13180        }
13181        if (DEBUG_MU) {
13182            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13183                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13184        }
13185        return result;
13186    }
13187
13188    public int bindService(IApplicationThread caller, IBinder token,
13189            Intent service, String resolvedType,
13190            IServiceConnection connection, int flags, int userId) {
13191        enforceNotIsolatedCaller("bindService");
13192        // Refuse possible leaked file descriptors
13193        if (service != null && service.hasFileDescriptors() == true) {
13194            throw new IllegalArgumentException("File descriptors passed in Intent");
13195        }
13196
13197        synchronized(this) {
13198            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13199                    connection, flags, userId);
13200        }
13201    }
13202
13203    public boolean unbindService(IServiceConnection connection) {
13204        synchronized (this) {
13205            return mServices.unbindServiceLocked(connection);
13206        }
13207    }
13208
13209    public void publishService(IBinder token, Intent intent, IBinder service) {
13210        // Refuse possible leaked file descriptors
13211        if (intent != null && intent.hasFileDescriptors() == true) {
13212            throw new IllegalArgumentException("File descriptors passed in Intent");
13213        }
13214
13215        synchronized(this) {
13216            if (!(token instanceof ServiceRecord)) {
13217                throw new IllegalArgumentException("Invalid service token");
13218            }
13219            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13220        }
13221    }
13222
13223    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13224        // Refuse possible leaked file descriptors
13225        if (intent != null && intent.hasFileDescriptors() == true) {
13226            throw new IllegalArgumentException("File descriptors passed in Intent");
13227        }
13228
13229        synchronized(this) {
13230            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13231        }
13232    }
13233
13234    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13235        synchronized(this) {
13236            if (!(token instanceof ServiceRecord)) {
13237                throw new IllegalArgumentException("Invalid service token");
13238            }
13239            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13240        }
13241    }
13242
13243    // =========================================================
13244    // BACKUP AND RESTORE
13245    // =========================================================
13246
13247    // Cause the target app to be launched if necessary and its backup agent
13248    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13249    // activity manager to announce its creation.
13250    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13251        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13252        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13253
13254        synchronized(this) {
13255            // !!! TODO: currently no check here that we're already bound
13256            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13257            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13258            synchronized (stats) {
13259                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13260            }
13261
13262            // Backup agent is now in use, its package can't be stopped.
13263            try {
13264                AppGlobals.getPackageManager().setPackageStoppedState(
13265                        app.packageName, false, UserHandle.getUserId(app.uid));
13266            } catch (RemoteException e) {
13267            } catch (IllegalArgumentException e) {
13268                Slog.w(TAG, "Failed trying to unstop package "
13269                        + app.packageName + ": " + e);
13270            }
13271
13272            BackupRecord r = new BackupRecord(ss, app, backupMode);
13273            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13274                    ? new ComponentName(app.packageName, app.backupAgentName)
13275                    : new ComponentName("android", "FullBackupAgent");
13276            // startProcessLocked() returns existing proc's record if it's already running
13277            ProcessRecord proc = startProcessLocked(app.processName, app,
13278                    false, 0, "backup", hostingName, false, false, false);
13279            if (proc == null) {
13280                Slog.e(TAG, "Unable to start backup agent process " + r);
13281                return false;
13282            }
13283
13284            r.app = proc;
13285            mBackupTarget = r;
13286            mBackupAppName = app.packageName;
13287
13288            // Try not to kill the process during backup
13289            updateOomAdjLocked(proc);
13290
13291            // If the process is already attached, schedule the creation of the backup agent now.
13292            // If it is not yet live, this will be done when it attaches to the framework.
13293            if (proc.thread != null) {
13294                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13295                try {
13296                    proc.thread.scheduleCreateBackupAgent(app,
13297                            compatibilityInfoForPackageLocked(app), backupMode);
13298                } catch (RemoteException e) {
13299                    // Will time out on the backup manager side
13300                }
13301            } else {
13302                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13303            }
13304            // Invariants: at this point, the target app process exists and the application
13305            // is either already running or in the process of coming up.  mBackupTarget and
13306            // mBackupAppName describe the app, so that when it binds back to the AM we
13307            // know that it's scheduled for a backup-agent operation.
13308        }
13309
13310        return true;
13311    }
13312
13313    @Override
13314    public void clearPendingBackup() {
13315        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13316        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13317
13318        synchronized (this) {
13319            mBackupTarget = null;
13320            mBackupAppName = null;
13321        }
13322    }
13323
13324    // A backup agent has just come up
13325    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13326        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13327                + " = " + agent);
13328
13329        synchronized(this) {
13330            if (!agentPackageName.equals(mBackupAppName)) {
13331                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13332                return;
13333            }
13334        }
13335
13336        long oldIdent = Binder.clearCallingIdentity();
13337        try {
13338            IBackupManager bm = IBackupManager.Stub.asInterface(
13339                    ServiceManager.getService(Context.BACKUP_SERVICE));
13340            bm.agentConnected(agentPackageName, agent);
13341        } catch (RemoteException e) {
13342            // can't happen; the backup manager service is local
13343        } catch (Exception e) {
13344            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13345            e.printStackTrace();
13346        } finally {
13347            Binder.restoreCallingIdentity(oldIdent);
13348        }
13349    }
13350
13351    // done with this agent
13352    public void unbindBackupAgent(ApplicationInfo appInfo) {
13353        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13354        if (appInfo == null) {
13355            Slog.w(TAG, "unbind backup agent for null app");
13356            return;
13357        }
13358
13359        synchronized(this) {
13360            try {
13361                if (mBackupAppName == null) {
13362                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13363                    return;
13364                }
13365
13366                if (!mBackupAppName.equals(appInfo.packageName)) {
13367                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13368                    return;
13369                }
13370
13371                // Not backing this app up any more; reset its OOM adjustment
13372                final ProcessRecord proc = mBackupTarget.app;
13373                updateOomAdjLocked(proc);
13374
13375                // If the app crashed during backup, 'thread' will be null here
13376                if (proc.thread != null) {
13377                    try {
13378                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13379                                compatibilityInfoForPackageLocked(appInfo));
13380                    } catch (Exception e) {
13381                        Slog.e(TAG, "Exception when unbinding backup agent:");
13382                        e.printStackTrace();
13383                    }
13384                }
13385            } finally {
13386                mBackupTarget = null;
13387                mBackupAppName = null;
13388            }
13389        }
13390    }
13391    // =========================================================
13392    // BROADCASTS
13393    // =========================================================
13394
13395    private final List getStickiesLocked(String action, IntentFilter filter,
13396            List cur, int userId) {
13397        final ContentResolver resolver = mContext.getContentResolver();
13398        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13399        if (stickies == null) {
13400            return cur;
13401        }
13402        final ArrayList<Intent> list = stickies.get(action);
13403        if (list == null) {
13404            return cur;
13405        }
13406        int N = list.size();
13407        for (int i=0; i<N; i++) {
13408            Intent intent = list.get(i);
13409            if (filter.match(resolver, intent, true, TAG) >= 0) {
13410                if (cur == null) {
13411                    cur = new ArrayList<Intent>();
13412                }
13413                cur.add(intent);
13414            }
13415        }
13416        return cur;
13417    }
13418
13419    boolean isPendingBroadcastProcessLocked(int pid) {
13420        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13421                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13422    }
13423
13424    void skipPendingBroadcastLocked(int pid) {
13425            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13426            for (BroadcastQueue queue : mBroadcastQueues) {
13427                queue.skipPendingBroadcastLocked(pid);
13428            }
13429    }
13430
13431    // The app just attached; send any pending broadcasts that it should receive
13432    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13433        boolean didSomething = false;
13434        for (BroadcastQueue queue : mBroadcastQueues) {
13435            didSomething |= queue.sendPendingBroadcastsLocked(app);
13436        }
13437        return didSomething;
13438    }
13439
13440    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13441            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13442        enforceNotIsolatedCaller("registerReceiver");
13443        int callingUid;
13444        int callingPid;
13445        synchronized(this) {
13446            ProcessRecord callerApp = null;
13447            if (caller != null) {
13448                callerApp = getRecordForAppLocked(caller);
13449                if (callerApp == null) {
13450                    throw new SecurityException(
13451                            "Unable to find app for caller " + caller
13452                            + " (pid=" + Binder.getCallingPid()
13453                            + ") when registering receiver " + receiver);
13454                }
13455                if (callerApp.info.uid != Process.SYSTEM_UID &&
13456                        !callerApp.pkgList.containsKey(callerPackage) &&
13457                        !"android".equals(callerPackage)) {
13458                    throw new SecurityException("Given caller package " + callerPackage
13459                            + " is not running in process " + callerApp);
13460                }
13461                callingUid = callerApp.info.uid;
13462                callingPid = callerApp.pid;
13463            } else {
13464                callerPackage = null;
13465                callingUid = Binder.getCallingUid();
13466                callingPid = Binder.getCallingPid();
13467            }
13468
13469            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13470                    true, true, "registerReceiver", callerPackage);
13471
13472            List allSticky = null;
13473
13474            // Look for any matching sticky broadcasts...
13475            Iterator actions = filter.actionsIterator();
13476            if (actions != null) {
13477                while (actions.hasNext()) {
13478                    String action = (String)actions.next();
13479                    allSticky = getStickiesLocked(action, filter, allSticky,
13480                            UserHandle.USER_ALL);
13481                    allSticky = getStickiesLocked(action, filter, allSticky,
13482                            UserHandle.getUserId(callingUid));
13483                }
13484            } else {
13485                allSticky = getStickiesLocked(null, filter, allSticky,
13486                        UserHandle.USER_ALL);
13487                allSticky = getStickiesLocked(null, filter, allSticky,
13488                        UserHandle.getUserId(callingUid));
13489            }
13490
13491            // The first sticky in the list is returned directly back to
13492            // the client.
13493            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13494
13495            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13496                    + ": " + sticky);
13497
13498            if (receiver == null) {
13499                return sticky;
13500            }
13501
13502            ReceiverList rl
13503                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13504            if (rl == null) {
13505                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13506                        userId, receiver);
13507                if (rl.app != null) {
13508                    rl.app.receivers.add(rl);
13509                } else {
13510                    try {
13511                        receiver.asBinder().linkToDeath(rl, 0);
13512                    } catch (RemoteException e) {
13513                        return sticky;
13514                    }
13515                    rl.linkedToDeath = true;
13516                }
13517                mRegisteredReceivers.put(receiver.asBinder(), rl);
13518            } else if (rl.uid != callingUid) {
13519                throw new IllegalArgumentException(
13520                        "Receiver requested to register for uid " + callingUid
13521                        + " was previously registered for uid " + rl.uid);
13522            } else if (rl.pid != callingPid) {
13523                throw new IllegalArgumentException(
13524                        "Receiver requested to register for pid " + callingPid
13525                        + " was previously registered for pid " + rl.pid);
13526            } else if (rl.userId != userId) {
13527                throw new IllegalArgumentException(
13528                        "Receiver requested to register for user " + userId
13529                        + " was previously registered for user " + rl.userId);
13530            }
13531            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13532                    permission, callingUid, userId);
13533            rl.add(bf);
13534            if (!bf.debugCheck()) {
13535                Slog.w(TAG, "==> For Dynamic broadast");
13536            }
13537            mReceiverResolver.addFilter(bf);
13538
13539            // Enqueue broadcasts for all existing stickies that match
13540            // this filter.
13541            if (allSticky != null) {
13542                ArrayList receivers = new ArrayList();
13543                receivers.add(bf);
13544
13545                int N = allSticky.size();
13546                for (int i=0; i<N; i++) {
13547                    Intent intent = (Intent)allSticky.get(i);
13548                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13549                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13550                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13551                            null, null, false, true, true, -1);
13552                    queue.enqueueParallelBroadcastLocked(r);
13553                    queue.scheduleBroadcastsLocked();
13554                }
13555            }
13556
13557            return sticky;
13558        }
13559    }
13560
13561    public void unregisterReceiver(IIntentReceiver receiver) {
13562        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13563
13564        final long origId = Binder.clearCallingIdentity();
13565        try {
13566            boolean doTrim = false;
13567
13568            synchronized(this) {
13569                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13570                if (rl != null) {
13571                    if (rl.curBroadcast != null) {
13572                        BroadcastRecord r = rl.curBroadcast;
13573                        final boolean doNext = finishReceiverLocked(
13574                                receiver.asBinder(), r.resultCode, r.resultData,
13575                                r.resultExtras, r.resultAbort);
13576                        if (doNext) {
13577                            doTrim = true;
13578                            r.queue.processNextBroadcast(false);
13579                        }
13580                    }
13581
13582                    if (rl.app != null) {
13583                        rl.app.receivers.remove(rl);
13584                    }
13585                    removeReceiverLocked(rl);
13586                    if (rl.linkedToDeath) {
13587                        rl.linkedToDeath = false;
13588                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13589                    }
13590                }
13591            }
13592
13593            // If we actually concluded any broadcasts, we might now be able
13594            // to trim the recipients' apps from our working set
13595            if (doTrim) {
13596                trimApplications();
13597                return;
13598            }
13599
13600        } finally {
13601            Binder.restoreCallingIdentity(origId);
13602        }
13603    }
13604
13605    void removeReceiverLocked(ReceiverList rl) {
13606        mRegisteredReceivers.remove(rl.receiver.asBinder());
13607        int N = rl.size();
13608        for (int i=0; i<N; i++) {
13609            mReceiverResolver.removeFilter(rl.get(i));
13610        }
13611    }
13612
13613    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13614        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13615            ProcessRecord r = mLruProcesses.get(i);
13616            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13617                try {
13618                    r.thread.dispatchPackageBroadcast(cmd, packages);
13619                } catch (RemoteException ex) {
13620                }
13621            }
13622        }
13623    }
13624
13625    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13626            int[] users) {
13627        List<ResolveInfo> receivers = null;
13628        try {
13629            HashSet<ComponentName> singleUserReceivers = null;
13630            boolean scannedFirstReceivers = false;
13631            for (int user : users) {
13632                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13633                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13634                if (user != 0 && newReceivers != null) {
13635                    // If this is not the primary user, we need to check for
13636                    // any receivers that should be filtered out.
13637                    for (int i=0; i<newReceivers.size(); i++) {
13638                        ResolveInfo ri = newReceivers.get(i);
13639                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13640                            newReceivers.remove(i);
13641                            i--;
13642                        }
13643                    }
13644                }
13645                if (newReceivers != null && newReceivers.size() == 0) {
13646                    newReceivers = null;
13647                }
13648                if (receivers == null) {
13649                    receivers = newReceivers;
13650                } else if (newReceivers != null) {
13651                    // We need to concatenate the additional receivers
13652                    // found with what we have do far.  This would be easy,
13653                    // but we also need to de-dup any receivers that are
13654                    // singleUser.
13655                    if (!scannedFirstReceivers) {
13656                        // Collect any single user receivers we had already retrieved.
13657                        scannedFirstReceivers = true;
13658                        for (int i=0; i<receivers.size(); i++) {
13659                            ResolveInfo ri = receivers.get(i);
13660                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13661                                ComponentName cn = new ComponentName(
13662                                        ri.activityInfo.packageName, ri.activityInfo.name);
13663                                if (singleUserReceivers == null) {
13664                                    singleUserReceivers = new HashSet<ComponentName>();
13665                                }
13666                                singleUserReceivers.add(cn);
13667                            }
13668                        }
13669                    }
13670                    // Add the new results to the existing results, tracking
13671                    // and de-dupping single user receivers.
13672                    for (int i=0; i<newReceivers.size(); i++) {
13673                        ResolveInfo ri = newReceivers.get(i);
13674                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13675                            ComponentName cn = new ComponentName(
13676                                    ri.activityInfo.packageName, ri.activityInfo.name);
13677                            if (singleUserReceivers == null) {
13678                                singleUserReceivers = new HashSet<ComponentName>();
13679                            }
13680                            if (!singleUserReceivers.contains(cn)) {
13681                                singleUserReceivers.add(cn);
13682                                receivers.add(ri);
13683                            }
13684                        } else {
13685                            receivers.add(ri);
13686                        }
13687                    }
13688                }
13689            }
13690        } catch (RemoteException ex) {
13691            // pm is in same process, this will never happen.
13692        }
13693        return receivers;
13694    }
13695
13696    private final int broadcastIntentLocked(ProcessRecord callerApp,
13697            String callerPackage, Intent intent, String resolvedType,
13698            IIntentReceiver resultTo, int resultCode, String resultData,
13699            Bundle map, String requiredPermission, int appOp,
13700            boolean ordered, boolean sticky, int callingPid, int callingUid,
13701            int userId) {
13702        intent = new Intent(intent);
13703
13704        // By default broadcasts do not go to stopped apps.
13705        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13706
13707        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13708            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13709            + " ordered=" + ordered + " userid=" + userId);
13710        if ((resultTo != null) && !ordered) {
13711            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13712        }
13713
13714        userId = handleIncomingUser(callingPid, callingUid, userId,
13715                true, false, "broadcast", callerPackage);
13716
13717        // Make sure that the user who is receiving this broadcast is started.
13718        // If not, we will just skip it.
13719        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13720            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13721                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13722                Slog.w(TAG, "Skipping broadcast of " + intent
13723                        + ": user " + userId + " is stopped");
13724                return ActivityManager.BROADCAST_SUCCESS;
13725            }
13726        }
13727
13728        /*
13729         * Prevent non-system code (defined here to be non-persistent
13730         * processes) from sending protected broadcasts.
13731         */
13732        int callingAppId = UserHandle.getAppId(callingUid);
13733        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13734            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13735            callingUid == 0) {
13736            // Always okay.
13737        } else if (callerApp == null || !callerApp.persistent) {
13738            try {
13739                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13740                        intent.getAction())) {
13741                    String msg = "Permission Denial: not allowed to send broadcast "
13742                            + intent.getAction() + " from pid="
13743                            + callingPid + ", uid=" + callingUid;
13744                    Slog.w(TAG, msg);
13745                    throw new SecurityException(msg);
13746                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13747                    // Special case for compatibility: we don't want apps to send this,
13748                    // but historically it has not been protected and apps may be using it
13749                    // to poke their own app widget.  So, instead of making it protected,
13750                    // just limit it to the caller.
13751                    if (callerApp == null) {
13752                        String msg = "Permission Denial: not allowed to send broadcast "
13753                                + intent.getAction() + " from unknown caller.";
13754                        Slog.w(TAG, msg);
13755                        throw new SecurityException(msg);
13756                    } else if (intent.getComponent() != null) {
13757                        // They are good enough to send to an explicit component...  verify
13758                        // it is being sent to the calling app.
13759                        if (!intent.getComponent().getPackageName().equals(
13760                                callerApp.info.packageName)) {
13761                            String msg = "Permission Denial: not allowed to send broadcast "
13762                                    + intent.getAction() + " to "
13763                                    + intent.getComponent().getPackageName() + " from "
13764                                    + callerApp.info.packageName;
13765                            Slog.w(TAG, msg);
13766                            throw new SecurityException(msg);
13767                        }
13768                    } else {
13769                        // Limit broadcast to their own package.
13770                        intent.setPackage(callerApp.info.packageName);
13771                    }
13772                }
13773            } catch (RemoteException e) {
13774                Slog.w(TAG, "Remote exception", e);
13775                return ActivityManager.BROADCAST_SUCCESS;
13776            }
13777        }
13778
13779        // Handle special intents: if this broadcast is from the package
13780        // manager about a package being removed, we need to remove all of
13781        // its activities from the history stack.
13782        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13783                intent.getAction());
13784        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13785                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13786                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13787                || uidRemoved) {
13788            if (checkComponentPermission(
13789                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13790                    callingPid, callingUid, -1, true)
13791                    == PackageManager.PERMISSION_GRANTED) {
13792                if (uidRemoved) {
13793                    final Bundle intentExtras = intent.getExtras();
13794                    final int uid = intentExtras != null
13795                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13796                    if (uid >= 0) {
13797                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13798                        synchronized (bs) {
13799                            bs.removeUidStatsLocked(uid);
13800                        }
13801                        mAppOpsService.uidRemoved(uid);
13802                    }
13803                } else {
13804                    // If resources are unavailable just force stop all
13805                    // those packages and flush the attribute cache as well.
13806                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13807                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13808                        if (list != null && (list.length > 0)) {
13809                            for (String pkg : list) {
13810                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13811                                        "storage unmount");
13812                            }
13813                            sendPackageBroadcastLocked(
13814                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13815                        }
13816                    } else {
13817                        Uri data = intent.getData();
13818                        String ssp;
13819                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13820                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13821                                    intent.getAction());
13822                            boolean fullUninstall = removed &&
13823                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13824                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13825                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13826                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13827                                        false, fullUninstall, userId,
13828                                        removed ? "pkg removed" : "pkg changed");
13829                            }
13830                            if (removed) {
13831                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13832                                        new String[] {ssp}, userId);
13833                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13834                                    mAppOpsService.packageRemoved(
13835                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13836
13837                                    // Remove all permissions granted from/to this package
13838                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13839                                }
13840                            }
13841                        }
13842                    }
13843                }
13844            } else {
13845                String msg = "Permission Denial: " + intent.getAction()
13846                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13847                        + ", uid=" + callingUid + ")"
13848                        + " requires "
13849                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13850                Slog.w(TAG, msg);
13851                throw new SecurityException(msg);
13852            }
13853
13854        // Special case for adding a package: by default turn on compatibility
13855        // mode.
13856        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13857            Uri data = intent.getData();
13858            String ssp;
13859            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13860                mCompatModePackages.handlePackageAddedLocked(ssp,
13861                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13862            }
13863        }
13864
13865        /*
13866         * If this is the time zone changed action, queue up a message that will reset the timezone
13867         * of all currently running processes. This message will get queued up before the broadcast
13868         * happens.
13869         */
13870        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13871            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13872        }
13873
13874        /*
13875         * If the user set the time, let all running processes know.
13876         */
13877        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13878            final int is24Hour = intent.getBooleanExtra(
13879                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13880            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13881        }
13882
13883        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13884            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13885        }
13886
13887        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13888            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13889            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13890        }
13891
13892        // Add to the sticky list if requested.
13893        if (sticky) {
13894            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13895                    callingPid, callingUid)
13896                    != PackageManager.PERMISSION_GRANTED) {
13897                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13898                        + callingPid + ", uid=" + callingUid
13899                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13900                Slog.w(TAG, msg);
13901                throw new SecurityException(msg);
13902            }
13903            if (requiredPermission != null) {
13904                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13905                        + " and enforce permission " + requiredPermission);
13906                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13907            }
13908            if (intent.getComponent() != null) {
13909                throw new SecurityException(
13910                        "Sticky broadcasts can't target a specific component");
13911            }
13912            // We use userId directly here, since the "all" target is maintained
13913            // as a separate set of sticky broadcasts.
13914            if (userId != UserHandle.USER_ALL) {
13915                // But first, if this is not a broadcast to all users, then
13916                // make sure it doesn't conflict with an existing broadcast to
13917                // all users.
13918                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13919                        UserHandle.USER_ALL);
13920                if (stickies != null) {
13921                    ArrayList<Intent> list = stickies.get(intent.getAction());
13922                    if (list != null) {
13923                        int N = list.size();
13924                        int i;
13925                        for (i=0; i<N; i++) {
13926                            if (intent.filterEquals(list.get(i))) {
13927                                throw new IllegalArgumentException(
13928                                        "Sticky broadcast " + intent + " for user "
13929                                        + userId + " conflicts with existing global broadcast");
13930                            }
13931                        }
13932                    }
13933                }
13934            }
13935            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13936            if (stickies == null) {
13937                stickies = new ArrayMap<String, ArrayList<Intent>>();
13938                mStickyBroadcasts.put(userId, stickies);
13939            }
13940            ArrayList<Intent> list = stickies.get(intent.getAction());
13941            if (list == null) {
13942                list = new ArrayList<Intent>();
13943                stickies.put(intent.getAction(), list);
13944            }
13945            int N = list.size();
13946            int i;
13947            for (i=0; i<N; i++) {
13948                if (intent.filterEquals(list.get(i))) {
13949                    // This sticky already exists, replace it.
13950                    list.set(i, new Intent(intent));
13951                    break;
13952                }
13953            }
13954            if (i >= N) {
13955                list.add(new Intent(intent));
13956            }
13957        }
13958
13959        int[] users;
13960        if (userId == UserHandle.USER_ALL) {
13961            // Caller wants broadcast to go to all started users.
13962            users = mStartedUserArray;
13963        } else {
13964            // Caller wants broadcast to go to one specific user.
13965            users = new int[] {userId};
13966        }
13967
13968        // Figure out who all will receive this broadcast.
13969        List receivers = null;
13970        List<BroadcastFilter> registeredReceivers = null;
13971        // Need to resolve the intent to interested receivers...
13972        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13973                 == 0) {
13974            receivers = collectReceiverComponents(intent, resolvedType, users);
13975        }
13976        if (intent.getComponent() == null) {
13977            registeredReceivers = mReceiverResolver.queryIntent(intent,
13978                    resolvedType, false, userId);
13979        }
13980
13981        final boolean replacePending =
13982                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13983
13984        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13985                + " replacePending=" + replacePending);
13986
13987        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13988        if (!ordered && NR > 0) {
13989            // If we are not serializing this broadcast, then send the
13990            // registered receivers separately so they don't wait for the
13991            // components to be launched.
13992            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13993            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13994                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13995                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13996                    ordered, sticky, false, userId);
13997            if (DEBUG_BROADCAST) Slog.v(
13998                    TAG, "Enqueueing parallel broadcast " + r);
13999            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14000            if (!replaced) {
14001                queue.enqueueParallelBroadcastLocked(r);
14002                queue.scheduleBroadcastsLocked();
14003            }
14004            registeredReceivers = null;
14005            NR = 0;
14006        }
14007
14008        // Merge into one list.
14009        int ir = 0;
14010        if (receivers != null) {
14011            // A special case for PACKAGE_ADDED: do not allow the package
14012            // being added to see this broadcast.  This prevents them from
14013            // using this as a back door to get run as soon as they are
14014            // installed.  Maybe in the future we want to have a special install
14015            // broadcast or such for apps, but we'd like to deliberately make
14016            // this decision.
14017            String skipPackages[] = null;
14018            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14019                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14020                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14021                Uri data = intent.getData();
14022                if (data != null) {
14023                    String pkgName = data.getSchemeSpecificPart();
14024                    if (pkgName != null) {
14025                        skipPackages = new String[] { pkgName };
14026                    }
14027                }
14028            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14029                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14030            }
14031            if (skipPackages != null && (skipPackages.length > 0)) {
14032                for (String skipPackage : skipPackages) {
14033                    if (skipPackage != null) {
14034                        int NT = receivers.size();
14035                        for (int it=0; it<NT; it++) {
14036                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14037                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14038                                receivers.remove(it);
14039                                it--;
14040                                NT--;
14041                            }
14042                        }
14043                    }
14044                }
14045            }
14046
14047            int NT = receivers != null ? receivers.size() : 0;
14048            int it = 0;
14049            ResolveInfo curt = null;
14050            BroadcastFilter curr = null;
14051            while (it < NT && ir < NR) {
14052                if (curt == null) {
14053                    curt = (ResolveInfo)receivers.get(it);
14054                }
14055                if (curr == null) {
14056                    curr = registeredReceivers.get(ir);
14057                }
14058                if (curr.getPriority() >= curt.priority) {
14059                    // Insert this broadcast record into the final list.
14060                    receivers.add(it, curr);
14061                    ir++;
14062                    curr = null;
14063                    it++;
14064                    NT++;
14065                } else {
14066                    // Skip to the next ResolveInfo in the final list.
14067                    it++;
14068                    curt = null;
14069                }
14070            }
14071        }
14072        while (ir < NR) {
14073            if (receivers == null) {
14074                receivers = new ArrayList();
14075            }
14076            receivers.add(registeredReceivers.get(ir));
14077            ir++;
14078        }
14079
14080        if ((receivers != null && receivers.size() > 0)
14081                || resultTo != null) {
14082            BroadcastQueue queue = broadcastQueueForIntent(intent);
14083            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14084                    callerPackage, callingPid, callingUid, resolvedType,
14085                    requiredPermission, appOp, receivers, resultTo, resultCode,
14086                    resultData, map, ordered, sticky, false, userId);
14087            if (DEBUG_BROADCAST) Slog.v(
14088                    TAG, "Enqueueing ordered broadcast " + r
14089                    + ": prev had " + queue.mOrderedBroadcasts.size());
14090            if (DEBUG_BROADCAST) {
14091                int seq = r.intent.getIntExtra("seq", -1);
14092                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14093            }
14094            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14095            if (!replaced) {
14096                queue.enqueueOrderedBroadcastLocked(r);
14097                queue.scheduleBroadcastsLocked();
14098            }
14099        }
14100
14101        return ActivityManager.BROADCAST_SUCCESS;
14102    }
14103
14104    final Intent verifyBroadcastLocked(Intent intent) {
14105        // Refuse possible leaked file descriptors
14106        if (intent != null && intent.hasFileDescriptors() == true) {
14107            throw new IllegalArgumentException("File descriptors passed in Intent");
14108        }
14109
14110        int flags = intent.getFlags();
14111
14112        if (!mProcessesReady) {
14113            // if the caller really truly claims to know what they're doing, go
14114            // ahead and allow the broadcast without launching any receivers
14115            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14116                intent = new Intent(intent);
14117                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14118            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14119                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14120                        + " before boot completion");
14121                throw new IllegalStateException("Cannot broadcast before boot completed");
14122            }
14123        }
14124
14125        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14126            throw new IllegalArgumentException(
14127                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14128        }
14129
14130        return intent;
14131    }
14132
14133    public final int broadcastIntent(IApplicationThread caller,
14134            Intent intent, String resolvedType, IIntentReceiver resultTo,
14135            int resultCode, String resultData, Bundle map,
14136            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14137        enforceNotIsolatedCaller("broadcastIntent");
14138        synchronized(this) {
14139            intent = verifyBroadcastLocked(intent);
14140
14141            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14142            final int callingPid = Binder.getCallingPid();
14143            final int callingUid = Binder.getCallingUid();
14144            final long origId = Binder.clearCallingIdentity();
14145            int res = broadcastIntentLocked(callerApp,
14146                    callerApp != null ? callerApp.info.packageName : null,
14147                    intent, resolvedType, resultTo,
14148                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14149                    callingPid, callingUid, userId);
14150            Binder.restoreCallingIdentity(origId);
14151            return res;
14152        }
14153    }
14154
14155    int broadcastIntentInPackage(String packageName, int uid,
14156            Intent intent, String resolvedType, IIntentReceiver resultTo,
14157            int resultCode, String resultData, Bundle map,
14158            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14159        synchronized(this) {
14160            intent = verifyBroadcastLocked(intent);
14161
14162            final long origId = Binder.clearCallingIdentity();
14163            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14164                    resultTo, resultCode, resultData, map, requiredPermission,
14165                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14166            Binder.restoreCallingIdentity(origId);
14167            return res;
14168        }
14169    }
14170
14171    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14172        // Refuse possible leaked file descriptors
14173        if (intent != null && intent.hasFileDescriptors() == true) {
14174            throw new IllegalArgumentException("File descriptors passed in Intent");
14175        }
14176
14177        userId = handleIncomingUser(Binder.getCallingPid(),
14178                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14179
14180        synchronized(this) {
14181            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14182                    != PackageManager.PERMISSION_GRANTED) {
14183                String msg = "Permission Denial: unbroadcastIntent() from pid="
14184                        + Binder.getCallingPid()
14185                        + ", uid=" + Binder.getCallingUid()
14186                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14187                Slog.w(TAG, msg);
14188                throw new SecurityException(msg);
14189            }
14190            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14191            if (stickies != null) {
14192                ArrayList<Intent> list = stickies.get(intent.getAction());
14193                if (list != null) {
14194                    int N = list.size();
14195                    int i;
14196                    for (i=0; i<N; i++) {
14197                        if (intent.filterEquals(list.get(i))) {
14198                            list.remove(i);
14199                            break;
14200                        }
14201                    }
14202                    if (list.size() <= 0) {
14203                        stickies.remove(intent.getAction());
14204                    }
14205                }
14206                if (stickies.size() <= 0) {
14207                    mStickyBroadcasts.remove(userId);
14208                }
14209            }
14210        }
14211    }
14212
14213    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14214            String resultData, Bundle resultExtras, boolean resultAbort) {
14215        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14216        if (r == null) {
14217            Slog.w(TAG, "finishReceiver called but not found on queue");
14218            return false;
14219        }
14220
14221        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14222    }
14223
14224    void backgroundServicesFinishedLocked(int userId) {
14225        for (BroadcastQueue queue : mBroadcastQueues) {
14226            queue.backgroundServicesFinishedLocked(userId);
14227        }
14228    }
14229
14230    public void finishReceiver(IBinder who, int resultCode, String resultData,
14231            Bundle resultExtras, boolean resultAbort) {
14232        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14233
14234        // Refuse possible leaked file descriptors
14235        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14236            throw new IllegalArgumentException("File descriptors passed in Bundle");
14237        }
14238
14239        final long origId = Binder.clearCallingIdentity();
14240        try {
14241            boolean doNext = false;
14242            BroadcastRecord r;
14243
14244            synchronized(this) {
14245                r = broadcastRecordForReceiverLocked(who);
14246                if (r != null) {
14247                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14248                        resultData, resultExtras, resultAbort, true);
14249                }
14250            }
14251
14252            if (doNext) {
14253                r.queue.processNextBroadcast(false);
14254            }
14255            trimApplications();
14256        } finally {
14257            Binder.restoreCallingIdentity(origId);
14258        }
14259    }
14260
14261    // =========================================================
14262    // INSTRUMENTATION
14263    // =========================================================
14264
14265    public boolean startInstrumentation(ComponentName className,
14266            String profileFile, int flags, Bundle arguments,
14267            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14268            int userId) {
14269        enforceNotIsolatedCaller("startInstrumentation");
14270        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14271                userId, false, true, "startInstrumentation", null);
14272        // Refuse possible leaked file descriptors
14273        if (arguments != null && arguments.hasFileDescriptors()) {
14274            throw new IllegalArgumentException("File descriptors passed in Bundle");
14275        }
14276
14277        synchronized(this) {
14278            InstrumentationInfo ii = null;
14279            ApplicationInfo ai = null;
14280            try {
14281                ii = mContext.getPackageManager().getInstrumentationInfo(
14282                    className, STOCK_PM_FLAGS);
14283                ai = AppGlobals.getPackageManager().getApplicationInfo(
14284                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14285            } catch (PackageManager.NameNotFoundException e) {
14286            } catch (RemoteException e) {
14287            }
14288            if (ii == null) {
14289                reportStartInstrumentationFailure(watcher, className,
14290                        "Unable to find instrumentation info for: " + className);
14291                return false;
14292            }
14293            if (ai == null) {
14294                reportStartInstrumentationFailure(watcher, className,
14295                        "Unable to find instrumentation target package: " + ii.targetPackage);
14296                return false;
14297            }
14298
14299            int match = mContext.getPackageManager().checkSignatures(
14300                    ii.targetPackage, ii.packageName);
14301            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14302                String msg = "Permission Denial: starting instrumentation "
14303                        + className + " from pid="
14304                        + Binder.getCallingPid()
14305                        + ", uid=" + Binder.getCallingPid()
14306                        + " not allowed because package " + ii.packageName
14307                        + " does not have a signature matching the target "
14308                        + ii.targetPackage;
14309                reportStartInstrumentationFailure(watcher, className, msg);
14310                throw new SecurityException(msg);
14311            }
14312
14313            final long origId = Binder.clearCallingIdentity();
14314            // Instrumentation can kill and relaunch even persistent processes
14315            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14316                    "start instr");
14317            ProcessRecord app = addAppLocked(ai, false);
14318            app.instrumentationClass = className;
14319            app.instrumentationInfo = ai;
14320            app.instrumentationProfileFile = profileFile;
14321            app.instrumentationArguments = arguments;
14322            app.instrumentationWatcher = watcher;
14323            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14324            app.instrumentationResultClass = className;
14325            Binder.restoreCallingIdentity(origId);
14326        }
14327
14328        return true;
14329    }
14330
14331    /**
14332     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14333     * error to the logs, but if somebody is watching, send the report there too.  This enables
14334     * the "am" command to report errors with more information.
14335     *
14336     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14337     * @param cn The component name of the instrumentation.
14338     * @param report The error report.
14339     */
14340    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14341            ComponentName cn, String report) {
14342        Slog.w(TAG, report);
14343        try {
14344            if (watcher != null) {
14345                Bundle results = new Bundle();
14346                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14347                results.putString("Error", report);
14348                watcher.instrumentationStatus(cn, -1, results);
14349            }
14350        } catch (RemoteException e) {
14351            Slog.w(TAG, e);
14352        }
14353    }
14354
14355    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14356        if (app.instrumentationWatcher != null) {
14357            try {
14358                // NOTE:  IInstrumentationWatcher *must* be oneway here
14359                app.instrumentationWatcher.instrumentationFinished(
14360                    app.instrumentationClass,
14361                    resultCode,
14362                    results);
14363            } catch (RemoteException e) {
14364            }
14365        }
14366        if (app.instrumentationUiAutomationConnection != null) {
14367            try {
14368                app.instrumentationUiAutomationConnection.shutdown();
14369            } catch (RemoteException re) {
14370                /* ignore */
14371            }
14372            // Only a UiAutomation can set this flag and now that
14373            // it is finished we make sure it is reset to its default.
14374            mUserIsMonkey = false;
14375        }
14376        app.instrumentationWatcher = null;
14377        app.instrumentationUiAutomationConnection = null;
14378        app.instrumentationClass = null;
14379        app.instrumentationInfo = null;
14380        app.instrumentationProfileFile = null;
14381        app.instrumentationArguments = null;
14382
14383        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14384                "finished inst");
14385    }
14386
14387    public void finishInstrumentation(IApplicationThread target,
14388            int resultCode, Bundle results) {
14389        int userId = UserHandle.getCallingUserId();
14390        // Refuse possible leaked file descriptors
14391        if (results != null && results.hasFileDescriptors()) {
14392            throw new IllegalArgumentException("File descriptors passed in Intent");
14393        }
14394
14395        synchronized(this) {
14396            ProcessRecord app = getRecordForAppLocked(target);
14397            if (app == null) {
14398                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14399                return;
14400            }
14401            final long origId = Binder.clearCallingIdentity();
14402            finishInstrumentationLocked(app, resultCode, results);
14403            Binder.restoreCallingIdentity(origId);
14404        }
14405    }
14406
14407    // =========================================================
14408    // CONFIGURATION
14409    // =========================================================
14410
14411    public ConfigurationInfo getDeviceConfigurationInfo() {
14412        ConfigurationInfo config = new ConfigurationInfo();
14413        synchronized (this) {
14414            config.reqTouchScreen = mConfiguration.touchscreen;
14415            config.reqKeyboardType = mConfiguration.keyboard;
14416            config.reqNavigation = mConfiguration.navigation;
14417            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14418                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14419                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14420            }
14421            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14422                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14423                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14424            }
14425            config.reqGlEsVersion = GL_ES_VERSION;
14426        }
14427        return config;
14428    }
14429
14430    ActivityStack getFocusedStack() {
14431        return mStackSupervisor.getFocusedStack();
14432    }
14433
14434    public Configuration getConfiguration() {
14435        Configuration ci;
14436        synchronized(this) {
14437            ci = new Configuration(mConfiguration);
14438        }
14439        return ci;
14440    }
14441
14442    public void updatePersistentConfiguration(Configuration values) {
14443        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14444                "updateConfiguration()");
14445        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14446                "updateConfiguration()");
14447        if (values == null) {
14448            throw new NullPointerException("Configuration must not be null");
14449        }
14450
14451        synchronized(this) {
14452            final long origId = Binder.clearCallingIdentity();
14453            updateConfigurationLocked(values, null, true, false);
14454            Binder.restoreCallingIdentity(origId);
14455        }
14456    }
14457
14458    public void updateConfiguration(Configuration values) {
14459        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14460                "updateConfiguration()");
14461
14462        synchronized(this) {
14463            if (values == null && mWindowManager != null) {
14464                // sentinel: fetch the current configuration from the window manager
14465                values = mWindowManager.computeNewConfiguration();
14466            }
14467
14468            if (mWindowManager != null) {
14469                mProcessList.applyDisplaySize(mWindowManager);
14470            }
14471
14472            final long origId = Binder.clearCallingIdentity();
14473            if (values != null) {
14474                Settings.System.clearConfiguration(values);
14475            }
14476            updateConfigurationLocked(values, null, false, false);
14477            Binder.restoreCallingIdentity(origId);
14478        }
14479    }
14480
14481    /**
14482     * Do either or both things: (1) change the current configuration, and (2)
14483     * make sure the given activity is running with the (now) current
14484     * configuration.  Returns true if the activity has been left running, or
14485     * false if <var>starting</var> is being destroyed to match the new
14486     * configuration.
14487     * @param persistent TODO
14488     */
14489    boolean updateConfigurationLocked(Configuration values,
14490            ActivityRecord starting, boolean persistent, boolean initLocale) {
14491        int changes = 0;
14492
14493        if (values != null) {
14494            Configuration newConfig = new Configuration(mConfiguration);
14495            changes = newConfig.updateFrom(values);
14496            if (changes != 0) {
14497                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14498                    Slog.i(TAG, "Updating configuration to: " + values);
14499                }
14500
14501                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14502
14503                if (values.locale != null && !initLocale) {
14504                    saveLocaleLocked(values.locale,
14505                                     !values.locale.equals(mConfiguration.locale),
14506                                     values.userSetLocale);
14507                }
14508
14509                mConfigurationSeq++;
14510                if (mConfigurationSeq <= 0) {
14511                    mConfigurationSeq = 1;
14512                }
14513                newConfig.seq = mConfigurationSeq;
14514                mConfiguration = newConfig;
14515                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14516                mUsageStatsService.noteStartConfig(newConfig);
14517
14518                final Configuration configCopy = new Configuration(mConfiguration);
14519
14520                // TODO: If our config changes, should we auto dismiss any currently
14521                // showing dialogs?
14522                mShowDialogs = shouldShowDialogs(newConfig);
14523
14524                AttributeCache ac = AttributeCache.instance();
14525                if (ac != null) {
14526                    ac.updateConfiguration(configCopy);
14527                }
14528
14529                // Make sure all resources in our process are updated
14530                // right now, so that anyone who is going to retrieve
14531                // resource values after we return will be sure to get
14532                // the new ones.  This is especially important during
14533                // boot, where the first config change needs to guarantee
14534                // all resources have that config before following boot
14535                // code is executed.
14536                mSystemThread.applyConfigurationToResources(configCopy);
14537
14538                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14539                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14540                    msg.obj = new Configuration(configCopy);
14541                    mHandler.sendMessage(msg);
14542                }
14543
14544                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14545                    ProcessRecord app = mLruProcesses.get(i);
14546                    try {
14547                        if (app.thread != null) {
14548                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14549                                    + app.processName + " new config " + mConfiguration);
14550                            app.thread.scheduleConfigurationChanged(configCopy);
14551                        }
14552                    } catch (Exception e) {
14553                    }
14554                }
14555                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14556                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14557                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14558                        | Intent.FLAG_RECEIVER_FOREGROUND);
14559                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14560                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14561                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14562                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14563                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14564                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14565                    broadcastIntentLocked(null, null, intent,
14566                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14567                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14568                }
14569            }
14570        }
14571
14572        boolean kept = true;
14573        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14574        // mainStack is null during startup.
14575        if (mainStack != null) {
14576            if (changes != 0 && starting == null) {
14577                // If the configuration changed, and the caller is not already
14578                // in the process of starting an activity, then find the top
14579                // activity to check if its configuration needs to change.
14580                starting = mainStack.topRunningActivityLocked(null);
14581            }
14582
14583            if (starting != null) {
14584                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14585                // And we need to make sure at this point that all other activities
14586                // are made visible with the correct configuration.
14587                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14588            }
14589        }
14590
14591        if (values != null && mWindowManager != null) {
14592            mWindowManager.setNewConfiguration(mConfiguration);
14593        }
14594
14595        return kept;
14596    }
14597
14598    /**
14599     * Decide based on the configuration whether we should shouw the ANR,
14600     * crash, etc dialogs.  The idea is that if there is no affordnace to
14601     * press the on-screen buttons, we shouldn't show the dialog.
14602     *
14603     * A thought: SystemUI might also want to get told about this, the Power
14604     * dialog / global actions also might want different behaviors.
14605     */
14606    private static final boolean shouldShowDialogs(Configuration config) {
14607        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14608                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14609    }
14610
14611    /**
14612     * Save the locale.  You must be inside a synchronized (this) block.
14613     */
14614    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14615        if(isDiff) {
14616            SystemProperties.set("user.language", l.getLanguage());
14617            SystemProperties.set("user.region", l.getCountry());
14618        }
14619
14620        if(isPersist) {
14621            SystemProperties.set("persist.sys.language", l.getLanguage());
14622            SystemProperties.set("persist.sys.country", l.getCountry());
14623            SystemProperties.set("persist.sys.localevar", l.getVariant());
14624        }
14625    }
14626
14627    @Override
14628    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14629        ActivityRecord srec = ActivityRecord.forToken(token);
14630        return srec != null && srec.task.affinity != null &&
14631                srec.task.affinity.equals(destAffinity);
14632    }
14633
14634    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14635            Intent resultData) {
14636
14637        synchronized (this) {
14638            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14639            if (stack != null) {
14640                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14641            }
14642            return false;
14643        }
14644    }
14645
14646    public int getLaunchedFromUid(IBinder activityToken) {
14647        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14648        if (srec == null) {
14649            return -1;
14650        }
14651        return srec.launchedFromUid;
14652    }
14653
14654    public String getLaunchedFromPackage(IBinder activityToken) {
14655        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14656        if (srec == null) {
14657            return null;
14658        }
14659        return srec.launchedFromPackage;
14660    }
14661
14662    // =========================================================
14663    // LIFETIME MANAGEMENT
14664    // =========================================================
14665
14666    // Returns which broadcast queue the app is the current [or imminent] receiver
14667    // on, or 'null' if the app is not an active broadcast recipient.
14668    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14669        BroadcastRecord r = app.curReceiver;
14670        if (r != null) {
14671            return r.queue;
14672        }
14673
14674        // It's not the current receiver, but it might be starting up to become one
14675        synchronized (this) {
14676            for (BroadcastQueue queue : mBroadcastQueues) {
14677                r = queue.mPendingBroadcast;
14678                if (r != null && r.curApp == app) {
14679                    // found it; report which queue it's in
14680                    return queue;
14681                }
14682            }
14683        }
14684
14685        return null;
14686    }
14687
14688    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14689            boolean doingAll, long now) {
14690        if (mAdjSeq == app.adjSeq) {
14691            // This adjustment has already been computed.
14692            return app.curRawAdj;
14693        }
14694
14695        if (app.thread == null) {
14696            app.adjSeq = mAdjSeq;
14697            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14698            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14699            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14700        }
14701
14702        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14703        app.adjSource = null;
14704        app.adjTarget = null;
14705        app.empty = false;
14706        app.cached = false;
14707
14708        final int activitiesSize = app.activities.size();
14709
14710        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14711            // The max adjustment doesn't allow this app to be anything
14712            // below foreground, so it is not worth doing work for it.
14713            app.adjType = "fixed";
14714            app.adjSeq = mAdjSeq;
14715            app.curRawAdj = app.maxAdj;
14716            app.foregroundActivities = false;
14717            app.keeping = true;
14718            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14719            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14720            // System processes can do UI, and when they do we want to have
14721            // them trim their memory after the user leaves the UI.  To
14722            // facilitate this, here we need to determine whether or not it
14723            // is currently showing UI.
14724            app.systemNoUi = true;
14725            if (app == TOP_APP) {
14726                app.systemNoUi = false;
14727            } else if (activitiesSize > 0) {
14728                for (int j = 0; j < activitiesSize; j++) {
14729                    final ActivityRecord r = app.activities.get(j);
14730                    if (r.visible) {
14731                        app.systemNoUi = false;
14732                    }
14733                }
14734            }
14735            if (!app.systemNoUi) {
14736                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14737            }
14738            return (app.curAdj=app.maxAdj);
14739        }
14740
14741        app.keeping = false;
14742        app.systemNoUi = false;
14743
14744        // Determine the importance of the process, starting with most
14745        // important to least, and assign an appropriate OOM adjustment.
14746        int adj;
14747        int schedGroup;
14748        int procState;
14749        boolean foregroundActivities = false;
14750        boolean interesting = false;
14751        BroadcastQueue queue;
14752        if (app == TOP_APP) {
14753            // The last app on the list is the foreground app.
14754            adj = ProcessList.FOREGROUND_APP_ADJ;
14755            schedGroup = Process.THREAD_GROUP_DEFAULT;
14756            app.adjType = "top-activity";
14757            foregroundActivities = true;
14758            interesting = true;
14759            procState = ActivityManager.PROCESS_STATE_TOP;
14760        } else if (app.instrumentationClass != null) {
14761            // Don't want to kill running instrumentation.
14762            adj = ProcessList.FOREGROUND_APP_ADJ;
14763            schedGroup = Process.THREAD_GROUP_DEFAULT;
14764            app.adjType = "instrumentation";
14765            interesting = true;
14766            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14767        } else if ((queue = isReceivingBroadcast(app)) != null) {
14768            // An app that is currently receiving a broadcast also
14769            // counts as being in the foreground for OOM killer purposes.
14770            // It's placed in a sched group based on the nature of the
14771            // broadcast as reflected by which queue it's active in.
14772            adj = ProcessList.FOREGROUND_APP_ADJ;
14773            schedGroup = (queue == mFgBroadcastQueue)
14774                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14775            app.adjType = "broadcast";
14776            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14777        } else if (app.executingServices.size() > 0) {
14778            // An app that is currently executing a service callback also
14779            // counts as being in the foreground.
14780            adj = ProcessList.FOREGROUND_APP_ADJ;
14781            schedGroup = app.execServicesFg ?
14782                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14783            app.adjType = "exec-service";
14784            procState = ActivityManager.PROCESS_STATE_SERVICE;
14785            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14786        } else {
14787            // As far as we know the process is empty.  We may change our mind later.
14788            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14789            // At this point we don't actually know the adjustment.  Use the cached adj
14790            // value that the caller wants us to.
14791            adj = cachedAdj;
14792            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14793            app.cached = true;
14794            app.empty = true;
14795            app.adjType = "cch-empty";
14796        }
14797
14798        // Examine all activities if not already foreground.
14799        if (!foregroundActivities && activitiesSize > 0) {
14800            for (int j = 0; j < activitiesSize; j++) {
14801                final ActivityRecord r = app.activities.get(j);
14802                if (r.app != app) {
14803                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14804                            + app + "?!?");
14805                    continue;
14806                }
14807                if (r.visible) {
14808                    // App has a visible activity; only upgrade adjustment.
14809                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14810                        adj = ProcessList.VISIBLE_APP_ADJ;
14811                        app.adjType = "visible";
14812                    }
14813                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14814                        procState = ActivityManager.PROCESS_STATE_TOP;
14815                    }
14816                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14817                    app.cached = false;
14818                    app.empty = false;
14819                    foregroundActivities = true;
14820                    break;
14821                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14822                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14823                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14824                        app.adjType = "pausing";
14825                    }
14826                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14827                        procState = ActivityManager.PROCESS_STATE_TOP;
14828                    }
14829                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14830                    app.cached = false;
14831                    app.empty = false;
14832                    foregroundActivities = true;
14833                } else if (r.state == ActivityState.STOPPING) {
14834                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14835                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14836                        app.adjType = "stopping";
14837                    }
14838                    // For the process state, we will at this point consider the
14839                    // process to be cached.  It will be cached either as an activity
14840                    // or empty depending on whether the activity is finishing.  We do
14841                    // this so that we can treat the process as cached for purposes of
14842                    // memory trimming (determing current memory level, trim command to
14843                    // send to process) since there can be an arbitrary number of stopping
14844                    // processes and they should soon all go into the cached state.
14845                    if (!r.finishing) {
14846                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14847                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14848                        }
14849                    }
14850                    app.cached = false;
14851                    app.empty = false;
14852                    foregroundActivities = true;
14853                } else {
14854                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14855                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14856                        app.adjType = "cch-act";
14857                    }
14858                }
14859            }
14860        }
14861
14862        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14863            if (app.foregroundServices) {
14864                // The user is aware of this app, so make it visible.
14865                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14866                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14867                app.cached = false;
14868                app.adjType = "fg-service";
14869                schedGroup = Process.THREAD_GROUP_DEFAULT;
14870            } else if (app.forcingToForeground != null) {
14871                // The user is aware of this app, so make it visible.
14872                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14873                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14874                app.cached = false;
14875                app.adjType = "force-fg";
14876                app.adjSource = app.forcingToForeground;
14877                schedGroup = Process.THREAD_GROUP_DEFAULT;
14878            }
14879        }
14880
14881        if (app.foregroundServices) {
14882            interesting = true;
14883        }
14884
14885        if (app == mHeavyWeightProcess) {
14886            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14887                // We don't want to kill the current heavy-weight process.
14888                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14889                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14890                app.cached = false;
14891                app.adjType = "heavy";
14892            }
14893            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14894                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14895            }
14896        }
14897
14898        if (app == mHomeProcess) {
14899            if (adj > ProcessList.HOME_APP_ADJ) {
14900                // This process is hosting what we currently consider to be the
14901                // home app, so we don't want to let it go into the background.
14902                adj = ProcessList.HOME_APP_ADJ;
14903                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14904                app.cached = false;
14905                app.adjType = "home";
14906            }
14907            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14908                procState = ActivityManager.PROCESS_STATE_HOME;
14909            }
14910        }
14911
14912        if (app == mPreviousProcess && app.activities.size() > 0) {
14913            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14914                // This was the previous process that showed UI to the user.
14915                // We want to try to keep it around more aggressively, to give
14916                // a good experience around switching between two apps.
14917                adj = ProcessList.PREVIOUS_APP_ADJ;
14918                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14919                app.cached = false;
14920                app.adjType = "previous";
14921            }
14922            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14923                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14924            }
14925        }
14926
14927        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14928                + " reason=" + app.adjType);
14929
14930        // By default, we use the computed adjustment.  It may be changed if
14931        // there are applications dependent on our services or providers, but
14932        // this gives us a baseline and makes sure we don't get into an
14933        // infinite recursion.
14934        app.adjSeq = mAdjSeq;
14935        app.curRawAdj = adj;
14936        app.hasStartedServices = false;
14937
14938        if (mBackupTarget != null && app == mBackupTarget.app) {
14939            // If possible we want to avoid killing apps while they're being backed up
14940            if (adj > ProcessList.BACKUP_APP_ADJ) {
14941                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14942                adj = ProcessList.BACKUP_APP_ADJ;
14943                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14944                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14945                }
14946                app.adjType = "backup";
14947                app.cached = false;
14948            }
14949            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14950                procState = ActivityManager.PROCESS_STATE_BACKUP;
14951            }
14952        }
14953
14954        boolean mayBeTop = false;
14955
14956        for (int is = app.services.size()-1;
14957                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14958                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14959                        || procState > ActivityManager.PROCESS_STATE_TOP);
14960                is--) {
14961            ServiceRecord s = app.services.valueAt(is);
14962            if (s.startRequested) {
14963                app.hasStartedServices = true;
14964                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14965                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14966                }
14967                if (app.hasShownUi && app != mHomeProcess) {
14968                    // If this process has shown some UI, let it immediately
14969                    // go to the LRU list because it may be pretty heavy with
14970                    // UI stuff.  We'll tag it with a label just to help
14971                    // debug and understand what is going on.
14972                    if (adj > ProcessList.SERVICE_ADJ) {
14973                        app.adjType = "cch-started-ui-services";
14974                    }
14975                } else {
14976                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14977                        // This service has seen some activity within
14978                        // recent memory, so we will keep its process ahead
14979                        // of the background processes.
14980                        if (adj > ProcessList.SERVICE_ADJ) {
14981                            adj = ProcessList.SERVICE_ADJ;
14982                            app.adjType = "started-services";
14983                            app.cached = false;
14984                        }
14985                    }
14986                    // If we have let the service slide into the background
14987                    // state, still have some text describing what it is doing
14988                    // even though the service no longer has an impact.
14989                    if (adj > ProcessList.SERVICE_ADJ) {
14990                        app.adjType = "cch-started-services";
14991                    }
14992                }
14993                // Don't kill this process because it is doing work; it
14994                // has said it is doing work.
14995                app.keeping = true;
14996            }
14997            for (int conni = s.connections.size()-1;
14998                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14999                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15000                            || procState > ActivityManager.PROCESS_STATE_TOP);
15001                    conni--) {
15002                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15003                for (int i = 0;
15004                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15005                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15006                                || procState > ActivityManager.PROCESS_STATE_TOP);
15007                        i++) {
15008                    // XXX should compute this based on the max of
15009                    // all connected clients.
15010                    ConnectionRecord cr = clist.get(i);
15011                    if (cr.binding.client == app) {
15012                        // Binding to ourself is not interesting.
15013                        continue;
15014                    }
15015                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15016                        ProcessRecord client = cr.binding.client;
15017                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15018                                TOP_APP, doingAll, now);
15019                        int clientProcState = client.curProcState;
15020                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15021                            // If the other app is cached for any reason, for purposes here
15022                            // we are going to consider it empty.  The specific cached state
15023                            // doesn't propagate except under certain conditions.
15024                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15025                        }
15026                        String adjType = null;
15027                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15028                            // Not doing bind OOM management, so treat
15029                            // this guy more like a started service.
15030                            if (app.hasShownUi && app != mHomeProcess) {
15031                                // If this process has shown some UI, let it immediately
15032                                // go to the LRU list because it may be pretty heavy with
15033                                // UI stuff.  We'll tag it with a label just to help
15034                                // debug and understand what is going on.
15035                                if (adj > clientAdj) {
15036                                    adjType = "cch-bound-ui-services";
15037                                }
15038                                app.cached = false;
15039                                clientAdj = adj;
15040                                clientProcState = procState;
15041                            } else {
15042                                if (now >= (s.lastActivity
15043                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15044                                    // This service has not seen activity within
15045                                    // recent memory, so allow it to drop to the
15046                                    // LRU list if there is no other reason to keep
15047                                    // it around.  We'll also tag it with a label just
15048                                    // to help debug and undertand what is going on.
15049                                    if (adj > clientAdj) {
15050                                        adjType = "cch-bound-services";
15051                                    }
15052                                    clientAdj = adj;
15053                                }
15054                            }
15055                        }
15056                        if (adj > clientAdj) {
15057                            // If this process has recently shown UI, and
15058                            // the process that is binding to it is less
15059                            // important than being visible, then we don't
15060                            // care about the binding as much as we care
15061                            // about letting this process get into the LRU
15062                            // list to be killed and restarted if needed for
15063                            // memory.
15064                            if (app.hasShownUi && app != mHomeProcess
15065                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15066                                adjType = "cch-bound-ui-services";
15067                            } else {
15068                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15069                                        |Context.BIND_IMPORTANT)) != 0) {
15070                                    adj = clientAdj;
15071                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15072                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15073                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15074                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15075                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15076                                    adj = clientAdj;
15077                                } else {
15078                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15079                                        adj = ProcessList.VISIBLE_APP_ADJ;
15080                                    }
15081                                }
15082                                if (!client.cached) {
15083                                    app.cached = false;
15084                                }
15085                                if (client.keeping) {
15086                                    app.keeping = true;
15087                                }
15088                                adjType = "service";
15089                            }
15090                        }
15091                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15092                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15093                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15094                            }
15095                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15096                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15097                                    // Special handling of clients who are in the top state.
15098                                    // We *may* want to consider this process to be in the
15099                                    // top state as well, but only if there is not another
15100                                    // reason for it to be running.  Being on the top is a
15101                                    // special state, meaning you are specifically running
15102                                    // for the current top app.  If the process is already
15103                                    // running in the background for some other reason, it
15104                                    // is more important to continue considering it to be
15105                                    // in the background state.
15106                                    mayBeTop = true;
15107                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15108                                } else {
15109                                    // Special handling for above-top states (persistent
15110                                    // processes).  These should not bring the current process
15111                                    // into the top state, since they are not on top.  Instead
15112                                    // give them the best state after that.
15113                                    clientProcState =
15114                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15115                                }
15116                            }
15117                        } else {
15118                            if (clientProcState <
15119                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15120                                clientProcState =
15121                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15122                            }
15123                        }
15124                        if (procState > clientProcState) {
15125                            procState = clientProcState;
15126                        }
15127                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15128                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15129                            app.pendingUiClean = true;
15130                        }
15131                        if (adjType != null) {
15132                            app.adjType = adjType;
15133                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15134                                    .REASON_SERVICE_IN_USE;
15135                            app.adjSource = cr.binding.client;
15136                            app.adjSourceOom = clientAdj;
15137                            app.adjTarget = s.name;
15138                        }
15139                    }
15140                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15141                        app.treatLikeActivity = true;
15142                    }
15143                    final ActivityRecord a = cr.activity;
15144                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15145                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15146                                (a.visible || a.state == ActivityState.RESUMED
15147                                 || a.state == ActivityState.PAUSING)) {
15148                            adj = ProcessList.FOREGROUND_APP_ADJ;
15149                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15150                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15151                            }
15152                            app.cached = false;
15153                            app.adjType = "service";
15154                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15155                                    .REASON_SERVICE_IN_USE;
15156                            app.adjSource = a;
15157                            app.adjSourceOom = adj;
15158                            app.adjTarget = s.name;
15159                        }
15160                    }
15161                }
15162            }
15163        }
15164
15165        for (int provi = app.pubProviders.size()-1;
15166                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15167                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15168                        || procState > ActivityManager.PROCESS_STATE_TOP);
15169                provi--) {
15170            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15171            for (int i = cpr.connections.size()-1;
15172                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15173                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15174                            || procState > ActivityManager.PROCESS_STATE_TOP);
15175                    i--) {
15176                ContentProviderConnection conn = cpr.connections.get(i);
15177                ProcessRecord client = conn.client;
15178                if (client == app) {
15179                    // Being our own client is not interesting.
15180                    continue;
15181                }
15182                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15183                int clientProcState = client.curProcState;
15184                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15185                    // If the other app is cached for any reason, for purposes here
15186                    // we are going to consider it empty.
15187                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15188                }
15189                if (adj > clientAdj) {
15190                    if (app.hasShownUi && app != mHomeProcess
15191                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15192                        app.adjType = "cch-ui-provider";
15193                    } else {
15194                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15195                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15196                        app.adjType = "provider";
15197                    }
15198                    app.cached &= client.cached;
15199                    app.keeping |= client.keeping;
15200                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15201                            .REASON_PROVIDER_IN_USE;
15202                    app.adjSource = client;
15203                    app.adjSourceOom = clientAdj;
15204                    app.adjTarget = cpr.name;
15205                }
15206                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15207                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15208                        // Special handling of clients who are in the top state.
15209                        // We *may* want to consider this process to be in the
15210                        // top state as well, but only if there is not another
15211                        // reason for it to be running.  Being on the top is a
15212                        // special state, meaning you are specifically running
15213                        // for the current top app.  If the process is already
15214                        // running in the background for some other reason, it
15215                        // is more important to continue considering it to be
15216                        // in the background state.
15217                        mayBeTop = true;
15218                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15219                    } else {
15220                        // Special handling for above-top states (persistent
15221                        // processes).  These should not bring the current process
15222                        // into the top state, since they are not on top.  Instead
15223                        // give them the best state after that.
15224                        clientProcState =
15225                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15226                    }
15227                }
15228                if (procState > clientProcState) {
15229                    procState = clientProcState;
15230                }
15231                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15232                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15233                }
15234            }
15235            // If the provider has external (non-framework) process
15236            // dependencies, ensure that its adjustment is at least
15237            // FOREGROUND_APP_ADJ.
15238            if (cpr.hasExternalProcessHandles()) {
15239                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15240                    adj = ProcessList.FOREGROUND_APP_ADJ;
15241                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15242                    app.cached = false;
15243                    app.keeping = true;
15244                    app.adjType = "provider";
15245                    app.adjTarget = cpr.name;
15246                }
15247                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15248                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15249                }
15250            }
15251        }
15252
15253        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15254            // A client of one of our services or providers is in the top state.  We
15255            // *may* want to be in the top state, but not if we are already running in
15256            // the background for some other reason.  For the decision here, we are going
15257            // to pick out a few specific states that we want to remain in when a client
15258            // is top (states that tend to be longer-term) and otherwise allow it to go
15259            // to the top state.
15260            switch (procState) {
15261                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15262                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15263                case ActivityManager.PROCESS_STATE_SERVICE:
15264                    // These all are longer-term states, so pull them up to the top
15265                    // of the background states, but not all the way to the top state.
15266                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15267                    break;
15268                default:
15269                    // Otherwise, top is a better choice, so take it.
15270                    procState = ActivityManager.PROCESS_STATE_TOP;
15271                    break;
15272            }
15273        }
15274
15275        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15276            if (app.hasClientActivities) {
15277                // This is a cached process, but with client activities.  Mark it so.
15278                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15279                app.adjType = "cch-client-act";
15280            } else if (app.treatLikeActivity) {
15281                // This is a cached process, but somebody wants us to treat it like it has
15282                // an activity, okay!
15283                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15284                app.adjType = "cch-as-act";
15285            }
15286        }
15287
15288        if (adj == ProcessList.SERVICE_ADJ) {
15289            if (doingAll) {
15290                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15291                mNewNumServiceProcs++;
15292                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15293                if (!app.serviceb) {
15294                    // This service isn't far enough down on the LRU list to
15295                    // normally be a B service, but if we are low on RAM and it
15296                    // is large we want to force it down since we would prefer to
15297                    // keep launcher over it.
15298                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15299                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15300                        app.serviceHighRam = true;
15301                        app.serviceb = true;
15302                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15303                    } else {
15304                        mNewNumAServiceProcs++;
15305                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15306                    }
15307                } else {
15308                    app.serviceHighRam = false;
15309                }
15310            }
15311            if (app.serviceb) {
15312                adj = ProcessList.SERVICE_B_ADJ;
15313            }
15314        }
15315
15316        app.curRawAdj = adj;
15317
15318        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15319        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15320        if (adj > app.maxAdj) {
15321            adj = app.maxAdj;
15322            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15323                schedGroup = Process.THREAD_GROUP_DEFAULT;
15324            }
15325        }
15326        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15327            app.keeping = true;
15328        }
15329
15330        // Do final modification to adj.  Everything we do between here and applying
15331        // the final setAdj must be done in this function, because we will also use
15332        // it when computing the final cached adj later.  Note that we don't need to
15333        // worry about this for max adj above, since max adj will always be used to
15334        // keep it out of the cached vaues.
15335        app.curAdj = app.modifyRawOomAdj(adj);
15336        app.curSchedGroup = schedGroup;
15337        app.curProcState = procState;
15338        app.foregroundActivities = foregroundActivities;
15339
15340        return app.curRawAdj;
15341    }
15342
15343    /**
15344     * Schedule PSS collection of a process.
15345     */
15346    void requestPssLocked(ProcessRecord proc, int procState) {
15347        if (mPendingPssProcesses.contains(proc)) {
15348            return;
15349        }
15350        if (mPendingPssProcesses.size() == 0) {
15351            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15352        }
15353        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15354        proc.pssProcState = procState;
15355        mPendingPssProcesses.add(proc);
15356    }
15357
15358    /**
15359     * Schedule PSS collection of all processes.
15360     */
15361    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15362        if (!always) {
15363            if (now < (mLastFullPssTime +
15364                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15365                return;
15366            }
15367        }
15368        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15369        mLastFullPssTime = now;
15370        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15371        mPendingPssProcesses.clear();
15372        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15373            ProcessRecord app = mLruProcesses.get(i);
15374            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15375                app.pssProcState = app.setProcState;
15376                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15377                        isSleeping(), now);
15378                mPendingPssProcesses.add(app);
15379            }
15380        }
15381        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15382    }
15383
15384    /**
15385     * Ask a given process to GC right now.
15386     */
15387    final void performAppGcLocked(ProcessRecord app) {
15388        try {
15389            app.lastRequestedGc = SystemClock.uptimeMillis();
15390            if (app.thread != null) {
15391                if (app.reportLowMemory) {
15392                    app.reportLowMemory = false;
15393                    app.thread.scheduleLowMemory();
15394                } else {
15395                    app.thread.processInBackground();
15396                }
15397            }
15398        } catch (Exception e) {
15399            // whatever.
15400        }
15401    }
15402
15403    /**
15404     * Returns true if things are idle enough to perform GCs.
15405     */
15406    private final boolean canGcNowLocked() {
15407        boolean processingBroadcasts = false;
15408        for (BroadcastQueue q : mBroadcastQueues) {
15409            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15410                processingBroadcasts = true;
15411            }
15412        }
15413        return !processingBroadcasts
15414                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15415    }
15416
15417    /**
15418     * Perform GCs on all processes that are waiting for it, but only
15419     * if things are idle.
15420     */
15421    final void performAppGcsLocked() {
15422        final int N = mProcessesToGc.size();
15423        if (N <= 0) {
15424            return;
15425        }
15426        if (canGcNowLocked()) {
15427            while (mProcessesToGc.size() > 0) {
15428                ProcessRecord proc = mProcessesToGc.remove(0);
15429                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15430                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15431                            <= SystemClock.uptimeMillis()) {
15432                        // To avoid spamming the system, we will GC processes one
15433                        // at a time, waiting a few seconds between each.
15434                        performAppGcLocked(proc);
15435                        scheduleAppGcsLocked();
15436                        return;
15437                    } else {
15438                        // It hasn't been long enough since we last GCed this
15439                        // process...  put it in the list to wait for its time.
15440                        addProcessToGcListLocked(proc);
15441                        break;
15442                    }
15443                }
15444            }
15445
15446            scheduleAppGcsLocked();
15447        }
15448    }
15449
15450    /**
15451     * If all looks good, perform GCs on all processes waiting for them.
15452     */
15453    final void performAppGcsIfAppropriateLocked() {
15454        if (canGcNowLocked()) {
15455            performAppGcsLocked();
15456            return;
15457        }
15458        // Still not idle, wait some more.
15459        scheduleAppGcsLocked();
15460    }
15461
15462    /**
15463     * Schedule the execution of all pending app GCs.
15464     */
15465    final void scheduleAppGcsLocked() {
15466        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15467
15468        if (mProcessesToGc.size() > 0) {
15469            // Schedule a GC for the time to the next process.
15470            ProcessRecord proc = mProcessesToGc.get(0);
15471            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15472
15473            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15474            long now = SystemClock.uptimeMillis();
15475            if (when < (now+GC_TIMEOUT)) {
15476                when = now + GC_TIMEOUT;
15477            }
15478            mHandler.sendMessageAtTime(msg, when);
15479        }
15480    }
15481
15482    /**
15483     * Add a process to the array of processes waiting to be GCed.  Keeps the
15484     * list in sorted order by the last GC time.  The process can't already be
15485     * on the list.
15486     */
15487    final void addProcessToGcListLocked(ProcessRecord proc) {
15488        boolean added = false;
15489        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15490            if (mProcessesToGc.get(i).lastRequestedGc <
15491                    proc.lastRequestedGc) {
15492                added = true;
15493                mProcessesToGc.add(i+1, proc);
15494                break;
15495            }
15496        }
15497        if (!added) {
15498            mProcessesToGc.add(0, proc);
15499        }
15500    }
15501
15502    /**
15503     * Set up to ask a process to GC itself.  This will either do it
15504     * immediately, or put it on the list of processes to gc the next
15505     * time things are idle.
15506     */
15507    final void scheduleAppGcLocked(ProcessRecord app) {
15508        long now = SystemClock.uptimeMillis();
15509        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15510            return;
15511        }
15512        if (!mProcessesToGc.contains(app)) {
15513            addProcessToGcListLocked(app);
15514            scheduleAppGcsLocked();
15515        }
15516    }
15517
15518    final void checkExcessivePowerUsageLocked(boolean doKills) {
15519        updateCpuStatsNow();
15520
15521        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15522        boolean doWakeKills = doKills;
15523        boolean doCpuKills = doKills;
15524        if (mLastPowerCheckRealtime == 0) {
15525            doWakeKills = false;
15526        }
15527        if (mLastPowerCheckUptime == 0) {
15528            doCpuKills = false;
15529        }
15530        if (stats.isScreenOn()) {
15531            doWakeKills = false;
15532        }
15533        final long curRealtime = SystemClock.elapsedRealtime();
15534        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15535        final long curUptime = SystemClock.uptimeMillis();
15536        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15537        mLastPowerCheckRealtime = curRealtime;
15538        mLastPowerCheckUptime = curUptime;
15539        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15540            doWakeKills = false;
15541        }
15542        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15543            doCpuKills = false;
15544        }
15545        int i = mLruProcesses.size();
15546        while (i > 0) {
15547            i--;
15548            ProcessRecord app = mLruProcesses.get(i);
15549            if (!app.keeping) {
15550                long wtime;
15551                synchronized (stats) {
15552                    wtime = stats.getProcessWakeTime(app.info.uid,
15553                            app.pid, curRealtime);
15554                }
15555                long wtimeUsed = wtime - app.lastWakeTime;
15556                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15557                if (DEBUG_POWER) {
15558                    StringBuilder sb = new StringBuilder(128);
15559                    sb.append("Wake for ");
15560                    app.toShortString(sb);
15561                    sb.append(": over ");
15562                    TimeUtils.formatDuration(realtimeSince, sb);
15563                    sb.append(" used ");
15564                    TimeUtils.formatDuration(wtimeUsed, sb);
15565                    sb.append(" (");
15566                    sb.append((wtimeUsed*100)/realtimeSince);
15567                    sb.append("%)");
15568                    Slog.i(TAG, sb.toString());
15569                    sb.setLength(0);
15570                    sb.append("CPU for ");
15571                    app.toShortString(sb);
15572                    sb.append(": over ");
15573                    TimeUtils.formatDuration(uptimeSince, sb);
15574                    sb.append(" used ");
15575                    TimeUtils.formatDuration(cputimeUsed, sb);
15576                    sb.append(" (");
15577                    sb.append((cputimeUsed*100)/uptimeSince);
15578                    sb.append("%)");
15579                    Slog.i(TAG, sb.toString());
15580                }
15581                // If a process has held a wake lock for more
15582                // than 50% of the time during this period,
15583                // that sounds bad.  Kill!
15584                if (doWakeKills && realtimeSince > 0
15585                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15586                    synchronized (stats) {
15587                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15588                                realtimeSince, wtimeUsed);
15589                    }
15590                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15591                            + " during " + realtimeSince);
15592                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15593                } else if (doCpuKills && uptimeSince > 0
15594                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15595                    synchronized (stats) {
15596                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15597                                uptimeSince, cputimeUsed);
15598                    }
15599                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15600                            + " during " + uptimeSince);
15601                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15602                } else {
15603                    app.lastWakeTime = wtime;
15604                    app.lastCpuTime = app.curCpuTime;
15605                }
15606            }
15607        }
15608    }
15609
15610    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15611            ProcessRecord TOP_APP, boolean doingAll, long now) {
15612        boolean success = true;
15613
15614        if (app.curRawAdj != app.setRawAdj) {
15615            if (wasKeeping && !app.keeping) {
15616                // This app is no longer something we want to keep.  Note
15617                // its current wake lock time to later know to kill it if
15618                // it is not behaving well.
15619                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15620                synchronized (stats) {
15621                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15622                            app.pid, SystemClock.elapsedRealtime());
15623                }
15624                app.lastCpuTime = app.curCpuTime;
15625            }
15626
15627            app.setRawAdj = app.curRawAdj;
15628        }
15629
15630        int changes = 0;
15631
15632        if (app.curAdj != app.setAdj) {
15633            ProcessList.setOomAdj(app.pid, app.curAdj);
15634            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15635                TAG, "Set " + app.pid + " " + app.processName +
15636                " adj " + app.curAdj + ": " + app.adjType);
15637            app.setAdj = app.curAdj;
15638        }
15639
15640        if (app.setSchedGroup != app.curSchedGroup) {
15641            app.setSchedGroup = app.curSchedGroup;
15642            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15643                    "Setting process group of " + app.processName
15644                    + " to " + app.curSchedGroup);
15645            if (app.waitingToKill != null &&
15646                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15647                killUnneededProcessLocked(app, app.waitingToKill);
15648                success = false;
15649            } else {
15650                if (true) {
15651                    long oldId = Binder.clearCallingIdentity();
15652                    try {
15653                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15654                    } catch (Exception e) {
15655                        Slog.w(TAG, "Failed setting process group of " + app.pid
15656                                + " to " + app.curSchedGroup);
15657                        e.printStackTrace();
15658                    } finally {
15659                        Binder.restoreCallingIdentity(oldId);
15660                    }
15661                } else {
15662                    if (app.thread != null) {
15663                        try {
15664                            app.thread.setSchedulingGroup(app.curSchedGroup);
15665                        } catch (RemoteException e) {
15666                        }
15667                    }
15668                }
15669                Process.setSwappiness(app.pid,
15670                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15671            }
15672        }
15673        if (app.repForegroundActivities != app.foregroundActivities) {
15674            app.repForegroundActivities = app.foregroundActivities;
15675            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15676        }
15677        if (app.repProcState != app.curProcState) {
15678            app.repProcState = app.curProcState;
15679            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15680            if (app.thread != null) {
15681                try {
15682                    if (false) {
15683                        //RuntimeException h = new RuntimeException("here");
15684                        Slog.i(TAG, "Sending new process state " + app.repProcState
15685                                + " to " + app /*, h*/);
15686                    }
15687                    app.thread.setProcessState(app.repProcState);
15688                } catch (RemoteException e) {
15689                }
15690            }
15691        }
15692        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15693                app.setProcState)) {
15694            app.lastStateTime = now;
15695            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15696                    isSleeping(), now);
15697            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15698                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15699                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15700                    + (app.nextPssTime-now) + ": " + app);
15701        } else {
15702            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15703                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15704                requestPssLocked(app, app.setProcState);
15705                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15706                        isSleeping(), now);
15707            } else if (false && DEBUG_PSS) {
15708                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15709            }
15710        }
15711        if (app.setProcState != app.curProcState) {
15712            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15713                    "Proc state change of " + app.processName
15714                    + " to " + app.curProcState);
15715            app.setProcState = app.curProcState;
15716            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15717                app.notCachedSinceIdle = false;
15718            }
15719            if (!doingAll) {
15720                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15721            } else {
15722                app.procStateChanged = true;
15723            }
15724        }
15725
15726        if (changes != 0) {
15727            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15728            int i = mPendingProcessChanges.size()-1;
15729            ProcessChangeItem item = null;
15730            while (i >= 0) {
15731                item = mPendingProcessChanges.get(i);
15732                if (item.pid == app.pid) {
15733                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15734                    break;
15735                }
15736                i--;
15737            }
15738            if (i < 0) {
15739                // No existing item in pending changes; need a new one.
15740                final int NA = mAvailProcessChanges.size();
15741                if (NA > 0) {
15742                    item = mAvailProcessChanges.remove(NA-1);
15743                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15744                } else {
15745                    item = new ProcessChangeItem();
15746                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15747                }
15748                item.changes = 0;
15749                item.pid = app.pid;
15750                item.uid = app.info.uid;
15751                if (mPendingProcessChanges.size() == 0) {
15752                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15753                            "*** Enqueueing dispatch processes changed!");
15754                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15755                }
15756                mPendingProcessChanges.add(item);
15757            }
15758            item.changes |= changes;
15759            item.processState = app.repProcState;
15760            item.foregroundActivities = app.repForegroundActivities;
15761            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15762                    + Integer.toHexString(System.identityHashCode(item))
15763                    + " " + app.toShortString() + ": changes=" + item.changes
15764                    + " procState=" + item.processState
15765                    + " foreground=" + item.foregroundActivities
15766                    + " type=" + app.adjType + " source=" + app.adjSource
15767                    + " target=" + app.adjTarget);
15768        }
15769
15770        return success;
15771    }
15772
15773    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15774        if (proc.thread != null && proc.baseProcessTracker != null) {
15775            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15776        }
15777    }
15778
15779    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15780            ProcessRecord TOP_APP, boolean doingAll, long now) {
15781        if (app.thread == null) {
15782            return false;
15783        }
15784
15785        final boolean wasKeeping = app.keeping;
15786
15787        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15788
15789        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15790    }
15791
15792    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15793            boolean oomAdj) {
15794        if (isForeground != proc.foregroundServices) {
15795            proc.foregroundServices = isForeground;
15796            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15797                    proc.info.uid);
15798            if (isForeground) {
15799                if (curProcs == null) {
15800                    curProcs = new ArrayList<ProcessRecord>();
15801                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15802                }
15803                if (!curProcs.contains(proc)) {
15804                    curProcs.add(proc);
15805                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15806                            proc.info.packageName, proc.info.uid);
15807                }
15808            } else {
15809                if (curProcs != null) {
15810                    if (curProcs.remove(proc)) {
15811                        mBatteryStatsService.noteEvent(
15812                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15813                                proc.info.packageName, proc.info.uid);
15814                        if (curProcs.size() <= 0) {
15815                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15816                        }
15817                    }
15818                }
15819            }
15820            if (oomAdj) {
15821                updateOomAdjLocked();
15822            }
15823        }
15824    }
15825
15826    private final ActivityRecord resumedAppLocked() {
15827        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15828        String pkg;
15829        int uid;
15830        if (act != null && !act.sleeping) {
15831            pkg = act.packageName;
15832            uid = act.info.applicationInfo.uid;
15833        } else {
15834            pkg = null;
15835            uid = -1;
15836        }
15837        // Has the UID or resumed package name changed?
15838        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15839                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15840            if (mCurResumedPackage != null) {
15841                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15842                        mCurResumedPackage, mCurResumedUid);
15843            }
15844            mCurResumedPackage = pkg;
15845            mCurResumedUid = uid;
15846            if (mCurResumedPackage != null) {
15847                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15848                        mCurResumedPackage, mCurResumedUid);
15849            }
15850        }
15851        return act;
15852    }
15853
15854    final boolean updateOomAdjLocked(ProcessRecord app) {
15855        final ActivityRecord TOP_ACT = resumedAppLocked();
15856        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15857        final boolean wasCached = app.cached;
15858
15859        mAdjSeq++;
15860
15861        // This is the desired cached adjusment we want to tell it to use.
15862        // If our app is currently cached, we know it, and that is it.  Otherwise,
15863        // we don't know it yet, and it needs to now be cached we will then
15864        // need to do a complete oom adj.
15865        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15866                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15867        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15868                SystemClock.uptimeMillis());
15869        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15870            // Changed to/from cached state, so apps after it in the LRU
15871            // list may also be changed.
15872            updateOomAdjLocked();
15873        }
15874        return success;
15875    }
15876
15877    final void updateOomAdjLocked() {
15878        final ActivityRecord TOP_ACT = resumedAppLocked();
15879        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15880        final long now = SystemClock.uptimeMillis();
15881        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15882        final int N = mLruProcesses.size();
15883
15884        if (false) {
15885            RuntimeException e = new RuntimeException();
15886            e.fillInStackTrace();
15887            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15888        }
15889
15890        mAdjSeq++;
15891        mNewNumServiceProcs = 0;
15892        mNewNumAServiceProcs = 0;
15893
15894        final int emptyProcessLimit;
15895        final int cachedProcessLimit;
15896        if (mProcessLimit <= 0) {
15897            emptyProcessLimit = cachedProcessLimit = 0;
15898        } else if (mProcessLimit == 1) {
15899            emptyProcessLimit = 1;
15900            cachedProcessLimit = 0;
15901        } else {
15902            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15903            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15904        }
15905
15906        // Let's determine how many processes we have running vs.
15907        // how many slots we have for background processes; we may want
15908        // to put multiple processes in a slot of there are enough of
15909        // them.
15910        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15911                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15912        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15913        if (numEmptyProcs > cachedProcessLimit) {
15914            // If there are more empty processes than our limit on cached
15915            // processes, then use the cached process limit for the factor.
15916            // This ensures that the really old empty processes get pushed
15917            // down to the bottom, so if we are running low on memory we will
15918            // have a better chance at keeping around more cached processes
15919            // instead of a gazillion empty processes.
15920            numEmptyProcs = cachedProcessLimit;
15921        }
15922        int emptyFactor = numEmptyProcs/numSlots;
15923        if (emptyFactor < 1) emptyFactor = 1;
15924        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15925        if (cachedFactor < 1) cachedFactor = 1;
15926        int stepCached = 0;
15927        int stepEmpty = 0;
15928        int numCached = 0;
15929        int numEmpty = 0;
15930        int numTrimming = 0;
15931
15932        mNumNonCachedProcs = 0;
15933        mNumCachedHiddenProcs = 0;
15934
15935        // First update the OOM adjustment for each of the
15936        // application processes based on their current state.
15937        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15938        int nextCachedAdj = curCachedAdj+1;
15939        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15940        int nextEmptyAdj = curEmptyAdj+2;
15941        for (int i=N-1; i>=0; i--) {
15942            ProcessRecord app = mLruProcesses.get(i);
15943            if (!app.killedByAm && app.thread != null) {
15944                app.procStateChanged = false;
15945                final boolean wasKeeping = app.keeping;
15946                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15947
15948                // If we haven't yet assigned the final cached adj
15949                // to the process, do that now.
15950                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15951                    switch (app.curProcState) {
15952                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15953                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15954                            // This process is a cached process holding activities...
15955                            // assign it the next cached value for that type, and then
15956                            // step that cached level.
15957                            app.curRawAdj = curCachedAdj;
15958                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15959                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15960                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15961                                    + ")");
15962                            if (curCachedAdj != nextCachedAdj) {
15963                                stepCached++;
15964                                if (stepCached >= cachedFactor) {
15965                                    stepCached = 0;
15966                                    curCachedAdj = nextCachedAdj;
15967                                    nextCachedAdj += 2;
15968                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15969                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15970                                    }
15971                                }
15972                            }
15973                            break;
15974                        default:
15975                            // For everything else, assign next empty cached process
15976                            // level and bump that up.  Note that this means that
15977                            // long-running services that have dropped down to the
15978                            // cached level will be treated as empty (since their process
15979                            // state is still as a service), which is what we want.
15980                            app.curRawAdj = curEmptyAdj;
15981                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15982                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15983                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15984                                    + ")");
15985                            if (curEmptyAdj != nextEmptyAdj) {
15986                                stepEmpty++;
15987                                if (stepEmpty >= emptyFactor) {
15988                                    stepEmpty = 0;
15989                                    curEmptyAdj = nextEmptyAdj;
15990                                    nextEmptyAdj += 2;
15991                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15992                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15993                                    }
15994                                }
15995                            }
15996                            break;
15997                    }
15998                }
15999
16000                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16001
16002                // Count the number of process types.
16003                switch (app.curProcState) {
16004                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16005                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16006                        mNumCachedHiddenProcs++;
16007                        numCached++;
16008                        if (numCached > cachedProcessLimit) {
16009                            killUnneededProcessLocked(app, "cached #" + numCached);
16010                        }
16011                        break;
16012                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16013                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16014                                && app.lastActivityTime < oldTime) {
16015                            killUnneededProcessLocked(app, "empty for "
16016                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16017                                    / 1000) + "s");
16018                        } else {
16019                            numEmpty++;
16020                            if (numEmpty > emptyProcessLimit) {
16021                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16022                            }
16023                        }
16024                        break;
16025                    default:
16026                        mNumNonCachedProcs++;
16027                        break;
16028                }
16029
16030                if (app.isolated && app.services.size() <= 0) {
16031                    // If this is an isolated process, and there are no
16032                    // services running in it, then the process is no longer
16033                    // needed.  We agressively kill these because we can by
16034                    // definition not re-use the same process again, and it is
16035                    // good to avoid having whatever code was running in them
16036                    // left sitting around after no longer needed.
16037                    killUnneededProcessLocked(app, "isolated not needed");
16038                }
16039
16040                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16041                        && !app.killedByAm) {
16042                    numTrimming++;
16043                }
16044            }
16045        }
16046
16047        mNumServiceProcs = mNewNumServiceProcs;
16048
16049        // Now determine the memory trimming level of background processes.
16050        // Unfortunately we need to start at the back of the list to do this
16051        // properly.  We only do this if the number of background apps we
16052        // are managing to keep around is less than half the maximum we desire;
16053        // if we are keeping a good number around, we'll let them use whatever
16054        // memory they want.
16055        final int numCachedAndEmpty = numCached + numEmpty;
16056        int memFactor;
16057        if (numCached <= ProcessList.TRIM_CACHED_APPS
16058                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16059            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16060                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16061            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16062                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16063            } else {
16064                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16065            }
16066        } else {
16067            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16068        }
16069        // We always allow the memory level to go up (better).  We only allow it to go
16070        // down if we are in a state where that is allowed, *and* the total number of processes
16071        // has gone down since last time.
16072        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16073                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16074                + " last=" + mLastNumProcesses);
16075        if (memFactor > mLastMemoryLevel) {
16076            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16077                memFactor = mLastMemoryLevel;
16078                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16079            }
16080        }
16081        mLastMemoryLevel = memFactor;
16082        mLastNumProcesses = mLruProcesses.size();
16083        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16084        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16085        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16086            if (mLowRamStartTime == 0) {
16087                mLowRamStartTime = now;
16088            }
16089            int step = 0;
16090            int fgTrimLevel;
16091            switch (memFactor) {
16092                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16093                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16094                    break;
16095                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16096                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16097                    break;
16098                default:
16099                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16100                    break;
16101            }
16102            int factor = numTrimming/3;
16103            int minFactor = 2;
16104            if (mHomeProcess != null) minFactor++;
16105            if (mPreviousProcess != null) minFactor++;
16106            if (factor < minFactor) factor = minFactor;
16107            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16108            for (int i=N-1; i>=0; i--) {
16109                ProcessRecord app = mLruProcesses.get(i);
16110                if (allChanged || app.procStateChanged) {
16111                    setProcessTrackerState(app, trackerMemFactor, now);
16112                    app.procStateChanged = false;
16113                }
16114                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16115                        && !app.killedByAm) {
16116                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16117                        try {
16118                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16119                                    "Trimming memory of " + app.processName
16120                                    + " to " + curLevel);
16121                            app.thread.scheduleTrimMemory(curLevel);
16122                        } catch (RemoteException e) {
16123                        }
16124                        if (false) {
16125                            // For now we won't do this; our memory trimming seems
16126                            // to be good enough at this point that destroying
16127                            // activities causes more harm than good.
16128                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16129                                    && app != mHomeProcess && app != mPreviousProcess) {
16130                                // Need to do this on its own message because the stack may not
16131                                // be in a consistent state at this point.
16132                                // For these apps we will also finish their activities
16133                                // to help them free memory.
16134                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16135                            }
16136                        }
16137                    }
16138                    app.trimMemoryLevel = curLevel;
16139                    step++;
16140                    if (step >= factor) {
16141                        step = 0;
16142                        switch (curLevel) {
16143                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16144                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16145                                break;
16146                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16147                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16148                                break;
16149                        }
16150                    }
16151                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16152                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16153                            && app.thread != null) {
16154                        try {
16155                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16156                                    "Trimming memory of heavy-weight " + app.processName
16157                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16158                            app.thread.scheduleTrimMemory(
16159                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16160                        } catch (RemoteException e) {
16161                        }
16162                    }
16163                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16164                } else {
16165                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16166                            || app.systemNoUi) && app.pendingUiClean) {
16167                        // If this application is now in the background and it
16168                        // had done UI, then give it the special trim level to
16169                        // have it free UI resources.
16170                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16171                        if (app.trimMemoryLevel < level && app.thread != null) {
16172                            try {
16173                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16174                                        "Trimming memory of bg-ui " + app.processName
16175                                        + " to " + level);
16176                                app.thread.scheduleTrimMemory(level);
16177                            } catch (RemoteException e) {
16178                            }
16179                        }
16180                        app.pendingUiClean = false;
16181                    }
16182                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16183                        try {
16184                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16185                                    "Trimming memory of fg " + app.processName
16186                                    + " to " + fgTrimLevel);
16187                            app.thread.scheduleTrimMemory(fgTrimLevel);
16188                        } catch (RemoteException e) {
16189                        }
16190                    }
16191                    app.trimMemoryLevel = fgTrimLevel;
16192                }
16193            }
16194        } else {
16195            if (mLowRamStartTime != 0) {
16196                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16197                mLowRamStartTime = 0;
16198            }
16199            for (int i=N-1; i>=0; i--) {
16200                ProcessRecord app = mLruProcesses.get(i);
16201                if (allChanged || app.procStateChanged) {
16202                    setProcessTrackerState(app, trackerMemFactor, now);
16203                    app.procStateChanged = false;
16204                }
16205                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16206                        || app.systemNoUi) && app.pendingUiClean) {
16207                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16208                            && app.thread != null) {
16209                        try {
16210                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16211                                    "Trimming memory of ui hidden " + app.processName
16212                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16213                            app.thread.scheduleTrimMemory(
16214                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16215                        } catch (RemoteException e) {
16216                        }
16217                    }
16218                    app.pendingUiClean = false;
16219                }
16220                app.trimMemoryLevel = 0;
16221            }
16222        }
16223
16224        if (mAlwaysFinishActivities) {
16225            // Need to do this on its own message because the stack may not
16226            // be in a consistent state at this point.
16227            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16228        }
16229
16230        if (allChanged) {
16231            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16232        }
16233
16234        if (mProcessStats.shouldWriteNowLocked(now)) {
16235            mHandler.post(new Runnable() {
16236                @Override public void run() {
16237                    synchronized (ActivityManagerService.this) {
16238                        mProcessStats.writeStateAsyncLocked();
16239                    }
16240                }
16241            });
16242        }
16243
16244        if (DEBUG_OOM_ADJ) {
16245            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16246        }
16247    }
16248
16249    final void trimApplications() {
16250        synchronized (this) {
16251            int i;
16252
16253            // First remove any unused application processes whose package
16254            // has been removed.
16255            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16256                final ProcessRecord app = mRemovedProcesses.get(i);
16257                if (app.activities.size() == 0
16258                        && app.curReceiver == null && app.services.size() == 0) {
16259                    Slog.i(
16260                        TAG, "Exiting empty application process "
16261                        + app.processName + " ("
16262                        + (app.thread != null ? app.thread.asBinder() : null)
16263                        + ")\n");
16264                    if (app.pid > 0 && app.pid != MY_PID) {
16265                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16266                                app.processName, app.setAdj, "empty");
16267                        app.killedByAm = true;
16268                        Process.killProcessQuiet(app.pid);
16269                    } else {
16270                        try {
16271                            app.thread.scheduleExit();
16272                        } catch (Exception e) {
16273                            // Ignore exceptions.
16274                        }
16275                    }
16276                    cleanUpApplicationRecordLocked(app, false, true, -1);
16277                    mRemovedProcesses.remove(i);
16278
16279                    if (app.persistent) {
16280                        if (app.persistent) {
16281                            addAppLocked(app.info, false);
16282                        }
16283                    }
16284                }
16285            }
16286
16287            // Now update the oom adj for all processes.
16288            updateOomAdjLocked();
16289        }
16290    }
16291
16292    /** This method sends the specified signal to each of the persistent apps */
16293    public void signalPersistentProcesses(int sig) throws RemoteException {
16294        if (sig != Process.SIGNAL_USR1) {
16295            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16296        }
16297
16298        synchronized (this) {
16299            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16300                    != PackageManager.PERMISSION_GRANTED) {
16301                throw new SecurityException("Requires permission "
16302                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16303            }
16304
16305            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16306                ProcessRecord r = mLruProcesses.get(i);
16307                if (r.thread != null && r.persistent) {
16308                    Process.sendSignal(r.pid, sig);
16309                }
16310            }
16311        }
16312    }
16313
16314    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16315        if (proc == null || proc == mProfileProc) {
16316            proc = mProfileProc;
16317            path = mProfileFile;
16318            profileType = mProfileType;
16319            clearProfilerLocked();
16320        }
16321        if (proc == null) {
16322            return;
16323        }
16324        try {
16325            proc.thread.profilerControl(false, path, null, profileType);
16326        } catch (RemoteException e) {
16327            throw new IllegalStateException("Process disappeared");
16328        }
16329    }
16330
16331    private void clearProfilerLocked() {
16332        if (mProfileFd != null) {
16333            try {
16334                mProfileFd.close();
16335            } catch (IOException e) {
16336            }
16337        }
16338        mProfileApp = null;
16339        mProfileProc = null;
16340        mProfileFile = null;
16341        mProfileType = 0;
16342        mAutoStopProfiler = false;
16343    }
16344
16345    public boolean profileControl(String process, int userId, boolean start,
16346            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16347
16348        try {
16349            synchronized (this) {
16350                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16351                // its own permission.
16352                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16353                        != PackageManager.PERMISSION_GRANTED) {
16354                    throw new SecurityException("Requires permission "
16355                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16356                }
16357
16358                if (start && fd == null) {
16359                    throw new IllegalArgumentException("null fd");
16360                }
16361
16362                ProcessRecord proc = null;
16363                if (process != null) {
16364                    proc = findProcessLocked(process, userId, "profileControl");
16365                }
16366
16367                if (start && (proc == null || proc.thread == null)) {
16368                    throw new IllegalArgumentException("Unknown process: " + process);
16369                }
16370
16371                if (start) {
16372                    stopProfilerLocked(null, null, 0);
16373                    setProfileApp(proc.info, proc.processName, path, fd, false);
16374                    mProfileProc = proc;
16375                    mProfileType = profileType;
16376                    try {
16377                        fd = fd.dup();
16378                    } catch (IOException e) {
16379                        fd = null;
16380                    }
16381                    proc.thread.profilerControl(start, path, fd, profileType);
16382                    fd = null;
16383                    mProfileFd = null;
16384                } else {
16385                    stopProfilerLocked(proc, path, profileType);
16386                    if (fd != null) {
16387                        try {
16388                            fd.close();
16389                        } catch (IOException e) {
16390                        }
16391                    }
16392                }
16393
16394                return true;
16395            }
16396        } catch (RemoteException e) {
16397            throw new IllegalStateException("Process disappeared");
16398        } finally {
16399            if (fd != null) {
16400                try {
16401                    fd.close();
16402                } catch (IOException e) {
16403                }
16404            }
16405        }
16406    }
16407
16408    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16409        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16410                userId, true, true, callName, null);
16411        ProcessRecord proc = null;
16412        try {
16413            int pid = Integer.parseInt(process);
16414            synchronized (mPidsSelfLocked) {
16415                proc = mPidsSelfLocked.get(pid);
16416            }
16417        } catch (NumberFormatException e) {
16418        }
16419
16420        if (proc == null) {
16421            ArrayMap<String, SparseArray<ProcessRecord>> all
16422                    = mProcessNames.getMap();
16423            SparseArray<ProcessRecord> procs = all.get(process);
16424            if (procs != null && procs.size() > 0) {
16425                proc = procs.valueAt(0);
16426                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16427                    for (int i=1; i<procs.size(); i++) {
16428                        ProcessRecord thisProc = procs.valueAt(i);
16429                        if (thisProc.userId == userId) {
16430                            proc = thisProc;
16431                            break;
16432                        }
16433                    }
16434                }
16435            }
16436        }
16437
16438        return proc;
16439    }
16440
16441    public boolean dumpHeap(String process, int userId, boolean managed,
16442            String path, ParcelFileDescriptor fd) throws RemoteException {
16443
16444        try {
16445            synchronized (this) {
16446                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16447                // its own permission (same as profileControl).
16448                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16449                        != PackageManager.PERMISSION_GRANTED) {
16450                    throw new SecurityException("Requires permission "
16451                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16452                }
16453
16454                if (fd == null) {
16455                    throw new IllegalArgumentException("null fd");
16456                }
16457
16458                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16459                if (proc == null || proc.thread == null) {
16460                    throw new IllegalArgumentException("Unknown process: " + process);
16461                }
16462
16463                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16464                if (!isDebuggable) {
16465                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16466                        throw new SecurityException("Process not debuggable: " + proc);
16467                    }
16468                }
16469
16470                proc.thread.dumpHeap(managed, path, fd);
16471                fd = null;
16472                return true;
16473            }
16474        } catch (RemoteException e) {
16475            throw new IllegalStateException("Process disappeared");
16476        } finally {
16477            if (fd != null) {
16478                try {
16479                    fd.close();
16480                } catch (IOException e) {
16481                }
16482            }
16483        }
16484    }
16485
16486    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16487    public void monitor() {
16488        synchronized (this) { }
16489    }
16490
16491    void onCoreSettingsChange(Bundle settings) {
16492        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16493            ProcessRecord processRecord = mLruProcesses.get(i);
16494            try {
16495                if (processRecord.thread != null) {
16496                    processRecord.thread.setCoreSettings(settings);
16497                }
16498            } catch (RemoteException re) {
16499                /* ignore */
16500            }
16501        }
16502    }
16503
16504    // Multi-user methods
16505
16506    /**
16507     * Start user, if its not already running, but don't bring it to foreground.
16508     */
16509    @Override
16510    public boolean startUserInBackground(final int userId) {
16511        return startUser(userId, /* foreground */ false);
16512    }
16513
16514    /**
16515     * Refreshes the list of users related to the current user when either a
16516     * user switch happens or when a new related user is started in the
16517     * background.
16518     */
16519    private void updateCurrentProfileIdsLocked() {
16520        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16521                mCurrentUserId, false /* enabledOnly */);
16522        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16523        for (int i = 0; i < currentProfileIds.length; i++) {
16524            currentProfileIds[i] = profiles.get(i).id;
16525        }
16526        mCurrentProfileIds = currentProfileIds;
16527    }
16528
16529    private Set getProfileIdsLocked(int userId) {
16530        Set userIds = new HashSet<Integer>();
16531        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16532                userId, false /* enabledOnly */);
16533        for (UserInfo user : profiles) {
16534            userIds.add(Integer.valueOf(user.id));
16535        }
16536        return userIds;
16537    }
16538
16539    @Override
16540    public boolean switchUser(final int userId) {
16541        return startUser(userId, /* foregound */ true);
16542    }
16543
16544    private boolean startUser(final int userId, boolean foreground) {
16545        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16546                != PackageManager.PERMISSION_GRANTED) {
16547            String msg = "Permission Denial: switchUser() from pid="
16548                    + Binder.getCallingPid()
16549                    + ", uid=" + Binder.getCallingUid()
16550                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16551            Slog.w(TAG, msg);
16552            throw new SecurityException(msg);
16553        }
16554
16555        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16556
16557        final long ident = Binder.clearCallingIdentity();
16558        try {
16559            synchronized (this) {
16560                final int oldUserId = mCurrentUserId;
16561                if (oldUserId == userId) {
16562                    return true;
16563                }
16564
16565                mStackSupervisor.setLockTaskModeLocked(null);
16566
16567                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16568                if (userInfo == null) {
16569                    Slog.w(TAG, "No user info for user #" + userId);
16570                    return false;
16571                }
16572
16573                if (foreground) {
16574                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16575                            R.anim.screen_user_enter);
16576                }
16577
16578                boolean needStart = false;
16579
16580                // If the user we are switching to is not currently started, then
16581                // we need to start it now.
16582                if (mStartedUsers.get(userId) == null) {
16583                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16584                    updateStartedUserArrayLocked();
16585                    needStart = true;
16586                }
16587
16588                final Integer userIdInt = Integer.valueOf(userId);
16589                mUserLru.remove(userIdInt);
16590                mUserLru.add(userIdInt);
16591
16592                if (foreground) {
16593                    mCurrentUserId = userId;
16594                    updateCurrentProfileIdsLocked();
16595                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16596                    // Once the internal notion of the active user has switched, we lock the device
16597                    // with the option to show the user switcher on the keyguard.
16598                    mWindowManager.lockNow(null);
16599                } else {
16600                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16601                    updateCurrentProfileIdsLocked();
16602                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16603                    mUserLru.remove(currentUserIdInt);
16604                    mUserLru.add(currentUserIdInt);
16605                }
16606
16607                final UserStartedState uss = mStartedUsers.get(userId);
16608
16609                // Make sure user is in the started state.  If it is currently
16610                // stopping, we need to knock that off.
16611                if (uss.mState == UserStartedState.STATE_STOPPING) {
16612                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16613                    // so we can just fairly silently bring the user back from
16614                    // the almost-dead.
16615                    uss.mState = UserStartedState.STATE_RUNNING;
16616                    updateStartedUserArrayLocked();
16617                    needStart = true;
16618                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16619                    // This means ACTION_SHUTDOWN has been sent, so we will
16620                    // need to treat this as a new boot of the user.
16621                    uss.mState = UserStartedState.STATE_BOOTING;
16622                    updateStartedUserArrayLocked();
16623                    needStart = true;
16624                }
16625
16626                if (uss.mState == UserStartedState.STATE_BOOTING) {
16627                    // Booting up a new user, need to tell system services about it.
16628                    // Note that this is on the same handler as scheduling of broadcasts,
16629                    // which is important because it needs to go first.
16630                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16631                }
16632
16633                if (foreground) {
16634                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16635                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16636                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16637                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16638                            oldUserId, userId, uss));
16639                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16640                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16641                }
16642
16643                if (needStart) {
16644                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16645                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16646                            | Intent.FLAG_RECEIVER_FOREGROUND);
16647                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16648                    broadcastIntentLocked(null, null, intent,
16649                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16650                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16651                }
16652
16653                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16654                    if (userId != UserHandle.USER_OWNER) {
16655                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16656                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16657                        broadcastIntentLocked(null, null, intent, null,
16658                                new IIntentReceiver.Stub() {
16659                                    public void performReceive(Intent intent, int resultCode,
16660                                            String data, Bundle extras, boolean ordered,
16661                                            boolean sticky, int sendingUser) {
16662                                        userInitialized(uss, userId);
16663                                    }
16664                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16665                                true, false, MY_PID, Process.SYSTEM_UID,
16666                                userId);
16667                        uss.initializing = true;
16668                    } else {
16669                        getUserManagerLocked().makeInitialized(userInfo.id);
16670                    }
16671                }
16672
16673                if (foreground) {
16674                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16675                    if (homeInFront) {
16676                        startHomeActivityLocked(userId);
16677                    } else {
16678                        mStackSupervisor.resumeTopActivitiesLocked();
16679                    }
16680                    EventLogTags.writeAmSwitchUser(userId);
16681                    getUserManagerLocked().userForeground(userId);
16682                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16683                } else {
16684                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16685                }
16686
16687                if (needStart) {
16688                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16689                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16690                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16691                    broadcastIntentLocked(null, null, intent,
16692                            null, new IIntentReceiver.Stub() {
16693                                @Override
16694                                public void performReceive(Intent intent, int resultCode, String data,
16695                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16696                                        throws RemoteException {
16697                                }
16698                            }, 0, null, null,
16699                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16700                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16701                }
16702            }
16703        } finally {
16704            Binder.restoreCallingIdentity(ident);
16705        }
16706
16707        return true;
16708    }
16709
16710    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16711        long ident = Binder.clearCallingIdentity();
16712        try {
16713            Intent intent;
16714            if (oldUserId >= 0) {
16715                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16716                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16717                        | Intent.FLAG_RECEIVER_FOREGROUND);
16718                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16719                broadcastIntentLocked(null, null, intent,
16720                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16721                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16722            }
16723            if (newUserId >= 0) {
16724                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16725                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16726                        | Intent.FLAG_RECEIVER_FOREGROUND);
16727                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16728                broadcastIntentLocked(null, null, intent,
16729                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16730                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16731                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16732                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16733                        | Intent.FLAG_RECEIVER_FOREGROUND);
16734                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16735                broadcastIntentLocked(null, null, intent,
16736                        null, null, 0, null, null,
16737                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16738                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16739            }
16740        } finally {
16741            Binder.restoreCallingIdentity(ident);
16742        }
16743    }
16744
16745    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16746            final int newUserId) {
16747        final int N = mUserSwitchObservers.beginBroadcast();
16748        if (N > 0) {
16749            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16750                int mCount = 0;
16751                @Override
16752                public void sendResult(Bundle data) throws RemoteException {
16753                    synchronized (ActivityManagerService.this) {
16754                        if (mCurUserSwitchCallback == this) {
16755                            mCount++;
16756                            if (mCount == N) {
16757                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16758                            }
16759                        }
16760                    }
16761                }
16762            };
16763            synchronized (this) {
16764                uss.switching = true;
16765                mCurUserSwitchCallback = callback;
16766            }
16767            for (int i=0; i<N; i++) {
16768                try {
16769                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16770                            newUserId, callback);
16771                } catch (RemoteException e) {
16772                }
16773            }
16774        } else {
16775            synchronized (this) {
16776                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16777            }
16778        }
16779        mUserSwitchObservers.finishBroadcast();
16780    }
16781
16782    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16783        synchronized (this) {
16784            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16785            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16786        }
16787    }
16788
16789    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16790        mCurUserSwitchCallback = null;
16791        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16792        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16793                oldUserId, newUserId, uss));
16794    }
16795
16796    void userInitialized(UserStartedState uss, int newUserId) {
16797        completeSwitchAndInitalize(uss, newUserId, true, false);
16798    }
16799
16800    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16801        completeSwitchAndInitalize(uss, newUserId, false, true);
16802    }
16803
16804    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16805            boolean clearInitializing, boolean clearSwitching) {
16806        boolean unfrozen = false;
16807        synchronized (this) {
16808            if (clearInitializing) {
16809                uss.initializing = false;
16810                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16811            }
16812            if (clearSwitching) {
16813                uss.switching = false;
16814            }
16815            if (!uss.switching && !uss.initializing) {
16816                mWindowManager.stopFreezingScreen();
16817                unfrozen = true;
16818            }
16819        }
16820        if (unfrozen) {
16821            final int N = mUserSwitchObservers.beginBroadcast();
16822            for (int i=0; i<N; i++) {
16823                try {
16824                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16825                } catch (RemoteException e) {
16826                }
16827            }
16828            mUserSwitchObservers.finishBroadcast();
16829        }
16830    }
16831
16832    void scheduleStartProfilesLocked() {
16833        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16834            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16835                    DateUtils.SECOND_IN_MILLIS);
16836        }
16837    }
16838
16839    void startProfilesLocked() {
16840        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16841        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16842                mCurrentUserId, false /* enabledOnly */);
16843        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16844        for (UserInfo user : profiles) {
16845            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16846                    && user.id != mCurrentUserId) {
16847                toStart.add(user);
16848            }
16849        }
16850        final int n = toStart.size();
16851        int i = 0;
16852        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16853            startUserInBackground(toStart.get(i).id);
16854        }
16855        if (i < n) {
16856            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16857        }
16858    }
16859
16860    void finishUserBoot(UserStartedState uss) {
16861        synchronized (this) {
16862            if (uss.mState == UserStartedState.STATE_BOOTING
16863                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16864                uss.mState = UserStartedState.STATE_RUNNING;
16865                final int userId = uss.mHandle.getIdentifier();
16866                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16867                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16868                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16869                broadcastIntentLocked(null, null, intent,
16870                        null, null, 0, null, null,
16871                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16872                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16873            }
16874        }
16875    }
16876
16877    void finishUserSwitch(UserStartedState uss) {
16878        synchronized (this) {
16879            finishUserBoot(uss);
16880
16881            startProfilesLocked();
16882
16883            int num = mUserLru.size();
16884            int i = 0;
16885            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16886                Integer oldUserId = mUserLru.get(i);
16887                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16888                if (oldUss == null) {
16889                    // Shouldn't happen, but be sane if it does.
16890                    mUserLru.remove(i);
16891                    num--;
16892                    continue;
16893                }
16894                if (oldUss.mState == UserStartedState.STATE_STOPPING
16895                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16896                    // This user is already stopping, doesn't count.
16897                    num--;
16898                    i++;
16899                    continue;
16900                }
16901                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16902                    // Owner and current can't be stopped, but count as running.
16903                    i++;
16904                    continue;
16905                }
16906                // This is a user to be stopped.
16907                stopUserLocked(oldUserId, null);
16908                num--;
16909                i++;
16910            }
16911        }
16912    }
16913
16914    @Override
16915    public int stopUser(final int userId, final IStopUserCallback callback) {
16916        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16917                != PackageManager.PERMISSION_GRANTED) {
16918            String msg = "Permission Denial: switchUser() from pid="
16919                    + Binder.getCallingPid()
16920                    + ", uid=" + Binder.getCallingUid()
16921                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16922            Slog.w(TAG, msg);
16923            throw new SecurityException(msg);
16924        }
16925        if (userId <= 0) {
16926            throw new IllegalArgumentException("Can't stop primary user " + userId);
16927        }
16928        synchronized (this) {
16929            return stopUserLocked(userId, callback);
16930        }
16931    }
16932
16933    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16934        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16935        if (mCurrentUserId == userId) {
16936            return ActivityManager.USER_OP_IS_CURRENT;
16937        }
16938
16939        final UserStartedState uss = mStartedUsers.get(userId);
16940        if (uss == null) {
16941            // User is not started, nothing to do...  but we do need to
16942            // callback if requested.
16943            if (callback != null) {
16944                mHandler.post(new Runnable() {
16945                    @Override
16946                    public void run() {
16947                        try {
16948                            callback.userStopped(userId);
16949                        } catch (RemoteException e) {
16950                        }
16951                    }
16952                });
16953            }
16954            return ActivityManager.USER_OP_SUCCESS;
16955        }
16956
16957        if (callback != null) {
16958            uss.mStopCallbacks.add(callback);
16959        }
16960
16961        if (uss.mState != UserStartedState.STATE_STOPPING
16962                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16963            uss.mState = UserStartedState.STATE_STOPPING;
16964            updateStartedUserArrayLocked();
16965
16966            long ident = Binder.clearCallingIdentity();
16967            try {
16968                // We are going to broadcast ACTION_USER_STOPPING and then
16969                // once that is done send a final ACTION_SHUTDOWN and then
16970                // stop the user.
16971                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16972                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16973                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16974                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16975                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16976                // This is the result receiver for the final shutdown broadcast.
16977                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16978                    @Override
16979                    public void performReceive(Intent intent, int resultCode, String data,
16980                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16981                        finishUserStop(uss);
16982                    }
16983                };
16984                // This is the result receiver for the initial stopping broadcast.
16985                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16986                    @Override
16987                    public void performReceive(Intent intent, int resultCode, String data,
16988                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16989                        // On to the next.
16990                        synchronized (ActivityManagerService.this) {
16991                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16992                                // Whoops, we are being started back up.  Abort, abort!
16993                                return;
16994                            }
16995                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16996                        }
16997                        mSystemServiceManager.stopUser(userId);
16998                        broadcastIntentLocked(null, null, shutdownIntent,
16999                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17000                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17001                    }
17002                };
17003                // Kick things off.
17004                broadcastIntentLocked(null, null, stoppingIntent,
17005                        null, stoppingReceiver, 0, null, null,
17006                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17007                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17008            } finally {
17009                Binder.restoreCallingIdentity(ident);
17010            }
17011        }
17012
17013        return ActivityManager.USER_OP_SUCCESS;
17014    }
17015
17016    void finishUserStop(UserStartedState uss) {
17017        final int userId = uss.mHandle.getIdentifier();
17018        boolean stopped;
17019        ArrayList<IStopUserCallback> callbacks;
17020        synchronized (this) {
17021            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17022            if (mStartedUsers.get(userId) != uss) {
17023                stopped = false;
17024            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17025                stopped = false;
17026            } else {
17027                stopped = true;
17028                // User can no longer run.
17029                mStartedUsers.remove(userId);
17030                mUserLru.remove(Integer.valueOf(userId));
17031                updateStartedUserArrayLocked();
17032
17033                // Clean up all state and processes associated with the user.
17034                // Kill all the processes for the user.
17035                forceStopUserLocked(userId, "finish user");
17036            }
17037        }
17038
17039        for (int i=0; i<callbacks.size(); i++) {
17040            try {
17041                if (stopped) callbacks.get(i).userStopped(userId);
17042                else callbacks.get(i).userStopAborted(userId);
17043            } catch (RemoteException e) {
17044            }
17045        }
17046
17047        if (stopped) {
17048            mSystemServiceManager.cleanupUser(userId);
17049            synchronized (this) {
17050                mStackSupervisor.removeUserLocked(userId);
17051            }
17052        }
17053    }
17054
17055    @Override
17056    public UserInfo getCurrentUser() {
17057        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17058                != PackageManager.PERMISSION_GRANTED) && (
17059                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17060                != PackageManager.PERMISSION_GRANTED)) {
17061            String msg = "Permission Denial: getCurrentUser() from pid="
17062                    + Binder.getCallingPid()
17063                    + ", uid=" + Binder.getCallingUid()
17064                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17065            Slog.w(TAG, msg);
17066            throw new SecurityException(msg);
17067        }
17068        synchronized (this) {
17069            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17070        }
17071    }
17072
17073    int getCurrentUserIdLocked() {
17074        return mCurrentUserId;
17075    }
17076
17077    @Override
17078    public boolean isUserRunning(int userId, boolean orStopped) {
17079        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17080                != PackageManager.PERMISSION_GRANTED) {
17081            String msg = "Permission Denial: isUserRunning() from pid="
17082                    + Binder.getCallingPid()
17083                    + ", uid=" + Binder.getCallingUid()
17084                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17085            Slog.w(TAG, msg);
17086            throw new SecurityException(msg);
17087        }
17088        synchronized (this) {
17089            return isUserRunningLocked(userId, orStopped);
17090        }
17091    }
17092
17093    boolean isUserRunningLocked(int userId, boolean orStopped) {
17094        UserStartedState state = mStartedUsers.get(userId);
17095        if (state == null) {
17096            return false;
17097        }
17098        if (orStopped) {
17099            return true;
17100        }
17101        return state.mState != UserStartedState.STATE_STOPPING
17102                && state.mState != UserStartedState.STATE_SHUTDOWN;
17103    }
17104
17105    @Override
17106    public int[] getRunningUserIds() {
17107        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17108                != PackageManager.PERMISSION_GRANTED) {
17109            String msg = "Permission Denial: isUserRunning() from pid="
17110                    + Binder.getCallingPid()
17111                    + ", uid=" + Binder.getCallingUid()
17112                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17113            Slog.w(TAG, msg);
17114            throw new SecurityException(msg);
17115        }
17116        synchronized (this) {
17117            return mStartedUserArray;
17118        }
17119    }
17120
17121    private void updateStartedUserArrayLocked() {
17122        int num = 0;
17123        for (int i=0; i<mStartedUsers.size();  i++) {
17124            UserStartedState uss = mStartedUsers.valueAt(i);
17125            // This list does not include stopping users.
17126            if (uss.mState != UserStartedState.STATE_STOPPING
17127                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17128                num++;
17129            }
17130        }
17131        mStartedUserArray = new int[num];
17132        num = 0;
17133        for (int i=0; i<mStartedUsers.size();  i++) {
17134            UserStartedState uss = mStartedUsers.valueAt(i);
17135            if (uss.mState != UserStartedState.STATE_STOPPING
17136                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17137                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17138                num++;
17139            }
17140        }
17141    }
17142
17143    @Override
17144    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17145        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17146                != PackageManager.PERMISSION_GRANTED) {
17147            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17148                    + Binder.getCallingPid()
17149                    + ", uid=" + Binder.getCallingUid()
17150                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17151            Slog.w(TAG, msg);
17152            throw new SecurityException(msg);
17153        }
17154
17155        mUserSwitchObservers.register(observer);
17156    }
17157
17158    @Override
17159    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17160        mUserSwitchObservers.unregister(observer);
17161    }
17162
17163    private boolean userExists(int userId) {
17164        if (userId == 0) {
17165            return true;
17166        }
17167        UserManagerService ums = getUserManagerLocked();
17168        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17169    }
17170
17171    int[] getUsersLocked() {
17172        UserManagerService ums = getUserManagerLocked();
17173        return ums != null ? ums.getUserIds() : new int[] { 0 };
17174    }
17175
17176    UserManagerService getUserManagerLocked() {
17177        if (mUserManager == null) {
17178            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17179            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17180        }
17181        return mUserManager;
17182    }
17183
17184    private int applyUserId(int uid, int userId) {
17185        return UserHandle.getUid(userId, uid);
17186    }
17187
17188    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17189        if (info == null) return null;
17190        ApplicationInfo newInfo = new ApplicationInfo(info);
17191        newInfo.uid = applyUserId(info.uid, userId);
17192        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17193                + info.packageName;
17194        return newInfo;
17195    }
17196
17197    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17198        if (aInfo == null
17199                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17200            return aInfo;
17201        }
17202
17203        ActivityInfo info = new ActivityInfo(aInfo);
17204        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17205        return info;
17206    }
17207
17208    private final class LocalService extends ActivityManagerInternal {
17209        @Override
17210        public void goingToSleep() {
17211            ActivityManagerService.this.goingToSleep();
17212        }
17213
17214        @Override
17215        public void wakingUp() {
17216            ActivityManagerService.this.wakingUp();
17217        }
17218    }
17219
17220    /**
17221     * An implementation of IAppTask, that allows an app to manage its own tasks via
17222     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17223     * only the process that calls getAppTasks() can call the AppTask methods.
17224     */
17225    class AppTaskImpl extends IAppTask.Stub {
17226        private int mTaskId;
17227        private int mCallingUid;
17228
17229        public AppTaskImpl(int taskId, int callingUid) {
17230            mTaskId = taskId;
17231            mCallingUid = callingUid;
17232        }
17233
17234        @Override
17235        public void finishAndRemoveTask() {
17236            // Ensure that we are called from the same process that created this AppTask
17237            if (mCallingUid != Binder.getCallingUid()) {
17238                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17239                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17240                return;
17241            }
17242
17243            synchronized (ActivityManagerService.this) {
17244                long origId = Binder.clearCallingIdentity();
17245                try {
17246                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17247                    if (tr != null) {
17248                        // Only kill the process if we are not a new document
17249                        int flags = tr.getBaseIntent().getFlags();
17250                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17251                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17252                        removeTaskByIdLocked(mTaskId,
17253                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17254                    }
17255                } finally {
17256                    Binder.restoreCallingIdentity(origId);
17257                }
17258            }
17259        }
17260
17261        @Override
17262        public ActivityManager.RecentTaskInfo getTaskInfo() {
17263            // Ensure that we are called from the same process that created this AppTask
17264            if (mCallingUid != Binder.getCallingUid()) {
17265                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17266                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17267                return null;
17268            }
17269
17270            synchronized (ActivityManagerService.this) {
17271                long origId = Binder.clearCallingIdentity();
17272                try {
17273                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17274                    if (tr != null) {
17275                        return createRecentTaskInfoFromTaskRecord(tr);
17276                    }
17277                } finally {
17278                    Binder.restoreCallingIdentity(origId);
17279                }
17280                return null;
17281            }
17282        }
17283    }
17284}
17285