ActivityManagerService.java revision d85fc72fb810858f7502e7e7f1bad53e1bf03edd
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.appwidget.AppWidgetManager;
36import android.graphics.Rect;
37import android.os.BatteryStats;
38import android.service.voice.IVoiceInteractionSession;
39import android.util.ArrayMap;
40
41import com.android.internal.R;
42import com.android.internal.annotations.GuardedBy;
43import com.android.internal.app.IAppOpsService;
44import com.android.internal.app.IVoiceInteractor;
45import com.android.internal.app.ProcessMap;
46import com.android.internal.app.ProcessStats;
47import com.android.internal.content.PackageMonitor;
48import com.android.internal.os.BackgroundThread;
49import com.android.internal.os.BatteryStatsImpl;
50import com.android.internal.os.ProcessCpuTracker;
51import com.android.internal.os.TransferPipe;
52import com.android.internal.os.Zygote;
53import com.android.internal.util.FastPrintWriter;
54import com.android.internal.util.FastXmlSerializer;
55import com.android.internal.util.MemInfoReader;
56import com.android.internal.util.Preconditions;
57import com.android.server.AppOpsService;
58import com.android.server.AttributeCache;
59import com.android.server.IntentResolver;
60import com.android.server.LocalServices;
61import com.android.server.ServiceThread;
62import com.android.server.SystemService;
63import com.android.server.SystemServiceManager;
64import com.android.server.Watchdog;
65import com.android.server.am.ActivityStack.ActivityState;
66import com.android.server.firewall.IntentFirewall;
67import com.android.server.pm.UserManagerService;
68import com.android.server.wm.AppTransition;
69import com.android.server.wm.WindowManagerService;
70import com.google.android.collect.Lists;
71import com.google.android.collect.Maps;
72
73import libcore.io.IoUtils;
74
75import org.xmlpull.v1.XmlPullParser;
76import org.xmlpull.v1.XmlPullParserException;
77import org.xmlpull.v1.XmlSerializer;
78
79import android.app.Activity;
80import android.app.ActivityManager;
81import android.app.ActivityManager.RunningTaskInfo;
82import android.app.ActivityManager.StackInfo;
83import android.app.ActivityManagerInternal;
84import android.app.ActivityManagerNative;
85import android.app.ActivityOptions;
86import android.app.ActivityThread;
87import android.app.AlertDialog;
88import android.app.AppGlobals;
89import android.app.ApplicationErrorReport;
90import android.app.Dialog;
91import android.app.IActivityController;
92import android.app.IApplicationThread;
93import android.app.IInstrumentationWatcher;
94import android.app.INotificationManager;
95import android.app.IProcessObserver;
96import android.app.IServiceConnection;
97import android.app.IStopUserCallback;
98import android.app.IUiAutomationConnection;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.backup.IBackupManager;
105import android.content.ActivityNotFoundException;
106import android.content.BroadcastReceiver;
107import android.content.ClipData;
108import android.content.ComponentCallbacks2;
109import android.content.ComponentName;
110import android.content.ContentProvider;
111import android.content.ContentResolver;
112import android.content.Context;
113import android.content.DialogInterface;
114import android.content.IContentProvider;
115import android.content.IIntentReceiver;
116import android.content.IIntentSender;
117import android.content.Intent;
118import android.content.IntentFilter;
119import android.content.IntentSender;
120import android.content.pm.ActivityInfo;
121import android.content.pm.ApplicationInfo;
122import android.content.pm.ConfigurationInfo;
123import android.content.pm.IPackageDataObserver;
124import android.content.pm.IPackageManager;
125import android.content.pm.InstrumentationInfo;
126import android.content.pm.PackageInfo;
127import android.content.pm.PackageManager;
128import android.content.pm.ParceledListSlice;
129import android.content.pm.UserInfo;
130import android.content.pm.PackageManager.NameNotFoundException;
131import android.content.pm.PathPermission;
132import android.content.pm.ProviderInfo;
133import android.content.pm.ResolveInfo;
134import android.content.pm.ServiceInfo;
135import android.content.res.CompatibilityInfo;
136import android.content.res.Configuration;
137import android.graphics.Bitmap;
138import android.net.Proxy;
139import android.net.ProxyInfo;
140import android.net.Uri;
141import android.os.Binder;
142import android.os.Build;
143import android.os.Bundle;
144import android.os.Debug;
145import android.os.DropBoxManager;
146import android.os.Environment;
147import android.os.FactoryTest;
148import android.os.FileObserver;
149import android.os.FileUtils;
150import android.os.Handler;
151import android.os.IBinder;
152import android.os.IPermissionController;
153import android.os.IRemoteCallback;
154import android.os.IUserManager;
155import android.os.Looper;
156import android.os.Message;
157import android.os.Parcel;
158import android.os.ParcelFileDescriptor;
159import android.os.Process;
160import android.os.RemoteCallbackList;
161import android.os.RemoteException;
162import android.os.SELinux;
163import android.os.ServiceManager;
164import android.os.StrictMode;
165import android.os.SystemClock;
166import android.os.SystemProperties;
167import android.os.UpdateLock;
168import android.os.UserHandle;
169import android.provider.Settings;
170import android.text.format.DateUtils;
171import android.text.format.Time;
172import android.util.AtomicFile;
173import android.util.EventLog;
174import android.util.Log;
175import android.util.Pair;
176import android.util.PrintWriterPrinter;
177import android.util.Slog;
178import android.util.SparseArray;
179import android.util.TimeUtils;
180import android.util.Xml;
181import android.view.Gravity;
182import android.view.LayoutInflater;
183import android.view.View;
184import android.view.WindowManager;
185
186import java.io.BufferedInputStream;
187import java.io.BufferedOutputStream;
188import java.io.DataInputStream;
189import java.io.DataOutputStream;
190import java.io.File;
191import java.io.FileDescriptor;
192import java.io.FileInputStream;
193import java.io.FileNotFoundException;
194import java.io.FileOutputStream;
195import java.io.IOException;
196import java.io.InputStreamReader;
197import java.io.PrintWriter;
198import java.io.StringWriter;
199import java.lang.ref.WeakReference;
200import java.util.ArrayList;
201import java.util.Arrays;
202import java.util.Collections;
203import java.util.Comparator;
204import java.util.HashMap;
205import java.util.HashSet;
206import java.util.Iterator;
207import java.util.List;
208import java.util.Locale;
209import java.util.Map;
210import java.util.Set;
211import java.util.concurrent.atomic.AtomicBoolean;
212import java.util.concurrent.atomic.AtomicLong;
213
214public final class ActivityManagerService extends ActivityManagerNative
215        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
216    private static final String USER_DATA_DIR = "/data/user/";
217    static final String TAG = "ActivityManager";
218    static final String TAG_MU = "ActivityManagerServiceMU";
219    static final boolean DEBUG = false;
220    static final boolean localLOGV = DEBUG;
221    static final boolean DEBUG_BACKUP = localLOGV || false;
222    static final boolean DEBUG_BROADCAST = localLOGV || false;
223    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
224    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
225    static final boolean DEBUG_CLEANUP = localLOGV || false;
226    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
227    static final boolean DEBUG_FOCUS = false;
228    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
229    static final boolean DEBUG_MU = localLOGV || false;
230    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
231    static final boolean DEBUG_LRU = localLOGV || false;
232    static final boolean DEBUG_PAUSE = localLOGV || false;
233    static final boolean DEBUG_POWER = localLOGV || false;
234    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
235    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
236    static final boolean DEBUG_PROCESSES = localLOGV || false;
237    static final boolean DEBUG_PROVIDER = localLOGV || false;
238    static final boolean DEBUG_RESULTS = localLOGV || false;
239    static final boolean DEBUG_SERVICE = localLOGV || false;
240    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
241    static final boolean DEBUG_STACK = localLOGV || false;
242    static final boolean DEBUG_SWITCH = localLOGV || false;
243    static final boolean DEBUG_TASKS = localLOGV || false;
244    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
245    static final boolean DEBUG_TRANSITION = localLOGV || false;
246    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
247    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
248    static final boolean DEBUG_VISBILITY = localLOGV || false;
249    static final boolean DEBUG_PSS = localLOGV || false;
250    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
251    static final boolean VALIDATE_TOKENS = false;
252    static final boolean SHOW_ACTIVITY_START_TIME = true;
253
254    // Control over CPU and battery monitoring.
255    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
256    static final boolean MONITOR_CPU_USAGE = true;
257    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
258    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
259    static final boolean MONITOR_THREAD_CPU_USAGE = false;
260
261    // The flags that are set for all calls we make to the package manager.
262    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
263
264    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
265
266    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
267
268    // Maximum number of recent tasks that we can remember.
269    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
270
271    // Amount of time after a call to stopAppSwitches() during which we will
272    // prevent further untrusted switches from happening.
273    static final long APP_SWITCH_DELAY_TIME = 5*1000;
274
275    // How long we wait for a launched process to attach to the activity manager
276    // before we decide it's never going to come up for real.
277    static final int PROC_START_TIMEOUT = 10*1000;
278
279    // How long we wait for a launched process to attach to the activity manager
280    // before we decide it's never going to come up for real, when the process was
281    // started with a wrapper for instrumentation (such as Valgrind) because it
282    // could take much longer than usual.
283    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
284
285    // How long to wait after going idle before forcing apps to GC.
286    static final int GC_TIMEOUT = 5*1000;
287
288    // The minimum amount of time between successive GC requests for a process.
289    static final int GC_MIN_INTERVAL = 60*1000;
290
291    // The minimum amount of time between successive PSS requests for a process.
292    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
293
294    // The minimum amount of time between successive PSS requests for a process
295    // when the request is due to the memory state being lowered.
296    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
297
298    // The rate at which we check for apps using excessive power -- 15 mins.
299    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
300
301    // The minimum sample duration we will allow before deciding we have
302    // enough data on wake locks to start killing things.
303    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on CPU usage to start killing things.
307    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // How long we allow a receiver to run before giving up on it.
310    static final int BROADCAST_FG_TIMEOUT = 10*1000;
311    static final int BROADCAST_BG_TIMEOUT = 60*1000;
312
313    // How long we wait until we timeout on key dispatching.
314    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
315
316    // How long we wait until we timeout on key dispatching during instrumentation.
317    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
318
319    // Amount of time we wait for observers to handle a user switch before
320    // giving up on them and unfreezing the screen.
321    static final int USER_SWITCH_TIMEOUT = 2*1000;
322
323    // Maximum number of users we allow to be running at a time.
324    static final int MAX_RUNNING_USERS = 3;
325
326    // How long to wait in getAssistContextExtras for the activity and foreground services
327    // to respond with the result.
328    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
329
330    // Maximum number of persisted Uri grants a package is allowed
331    static final int MAX_PERSISTED_URI_GRANTS = 128;
332
333    static final int MY_PID = Process.myPid();
334
335    static final String[] EMPTY_STRING_ARRAY = new String[0];
336
337    // How many bytes to write into the dropbox log before truncating
338    static final int DROPBOX_MAX_SIZE = 256 * 1024;
339
340    /** All system services */
341    SystemServiceManager mSystemServiceManager;
342
343    /** Run all ActivityStacks through this */
344    ActivityStackSupervisor mStackSupervisor;
345
346    public IntentFirewall mIntentFirewall;
347
348    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
349    // default actuion automatically.  Important for devices without direct input
350    // devices.
351    private boolean mShowDialogs = true;
352
353    /**
354     * Description of a request to start a new activity, which has been held
355     * due to app switches being disabled.
356     */
357    static class PendingActivityLaunch {
358        final ActivityRecord r;
359        final ActivityRecord sourceRecord;
360        final int startFlags;
361        final ActivityStack stack;
362
363        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
364                int _startFlags, ActivityStack _stack) {
365            r = _r;
366            sourceRecord = _sourceRecord;
367            startFlags = _startFlags;
368            stack = _stack;
369        }
370    }
371
372    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
373            = new ArrayList<PendingActivityLaunch>();
374
375    BroadcastQueue mFgBroadcastQueue;
376    BroadcastQueue mBgBroadcastQueue;
377    // Convenient for easy iteration over the queues. Foreground is first
378    // so that dispatch of foreground broadcasts gets precedence.
379    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
380
381    BroadcastQueue broadcastQueueForIntent(Intent intent) {
382        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
383        if (DEBUG_BACKGROUND_BROADCAST) {
384            Slog.i(TAG, "Broadcast intent " + intent + " on "
385                    + (isFg ? "foreground" : "background")
386                    + " queue");
387        }
388        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
389    }
390
391    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
392        for (BroadcastQueue queue : mBroadcastQueues) {
393            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
394            if (r != null) {
395                return r;
396            }
397        }
398        return null;
399    }
400
401    /**
402     * Activity we have told the window manager to have key focus.
403     */
404    ActivityRecord mFocusedActivity = null;
405
406    /**
407     * List of intents that were used to start the most recent tasks.
408     */
409    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
410
411    public class PendingAssistExtras extends Binder implements Runnable {
412        public final ActivityRecord activity;
413        public boolean haveResult = false;
414        public Bundle result = null;
415        public PendingAssistExtras(ActivityRecord _activity) {
416            activity = _activity;
417        }
418        @Override
419        public void run() {
420            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
421            synchronized (this) {
422                haveResult = true;
423                notifyAll();
424            }
425        }
426    }
427
428    final ArrayList<PendingAssistExtras> mPendingAssistExtras
429            = new ArrayList<PendingAssistExtras>();
430
431    /**
432     * Process management.
433     */
434    final ProcessList mProcessList = new ProcessList();
435
436    /**
437     * All of the applications we currently have running organized by name.
438     * The keys are strings of the application package name (as
439     * returned by the package manager), and the keys are ApplicationRecord
440     * objects.
441     */
442    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
443
444    /**
445     * Tracking long-term execution of processes to look for abuse and other
446     * bad app behavior.
447     */
448    final ProcessStatsService mProcessStats;
449
450    /**
451     * The currently running isolated processes.
452     */
453    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
454
455    /**
456     * Counter for assigning isolated process uids, to avoid frequently reusing the
457     * same ones.
458     */
459    int mNextIsolatedProcessUid = 0;
460
461    /**
462     * The currently running heavy-weight process, if any.
463     */
464    ProcessRecord mHeavyWeightProcess = null;
465
466    /**
467     * The last time that various processes have crashed.
468     */
469    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
470
471    /**
472     * Information about a process that is currently marked as bad.
473     */
474    static final class BadProcessInfo {
475        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
476            this.time = time;
477            this.shortMsg = shortMsg;
478            this.longMsg = longMsg;
479            this.stack = stack;
480        }
481
482        final long time;
483        final String shortMsg;
484        final String longMsg;
485        final String stack;
486    }
487
488    /**
489     * Set of applications that we consider to be bad, and will reject
490     * incoming broadcasts from (which the user has no control over).
491     * Processes are added to this set when they have crashed twice within
492     * a minimum amount of time; they are removed from it when they are
493     * later restarted (hopefully due to some user action).  The value is the
494     * time it was added to the list.
495     */
496    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
497
498    /**
499     * All of the processes we currently have running organized by pid.
500     * The keys are the pid running the application.
501     *
502     * <p>NOTE: This object is protected by its own lock, NOT the global
503     * activity manager lock!
504     */
505    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
506
507    /**
508     * All of the processes that have been forced to be foreground.  The key
509     * is the pid of the caller who requested it (we hold a death
510     * link on it).
511     */
512    abstract class ForegroundToken implements IBinder.DeathRecipient {
513        int pid;
514        IBinder token;
515    }
516    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
517
518    /**
519     * List of records for processes that someone had tried to start before the
520     * system was ready.  We don't start them at that point, but ensure they
521     * are started by the time booting is complete.
522     */
523    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
524
525    /**
526     * List of persistent applications that are in the process
527     * of being started.
528     */
529    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
530
531    /**
532     * Processes that are being forcibly torn down.
533     */
534    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
535
536    /**
537     * List of running applications, sorted by recent usage.
538     * The first entry in the list is the least recently used.
539     */
540    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
541
542    /**
543     * Where in mLruProcesses that the processes hosting activities start.
544     */
545    int mLruProcessActivityStart = 0;
546
547    /**
548     * Where in mLruProcesses that the processes hosting services start.
549     * This is after (lower index) than mLruProcessesActivityStart.
550     */
551    int mLruProcessServiceStart = 0;
552
553    /**
554     * List of processes that should gc as soon as things are idle.
555     */
556    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
557
558    /**
559     * Processes we want to collect PSS data from.
560     */
561    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
562
563    /**
564     * Last time we requested PSS data of all processes.
565     */
566    long mLastFullPssTime = SystemClock.uptimeMillis();
567
568    /**
569     * This is the process holding what we currently consider to be
570     * the "home" activity.
571     */
572    ProcessRecord mHomeProcess;
573
574    /**
575     * This is the process holding the activity the user last visited that
576     * is in a different process from the one they are currently in.
577     */
578    ProcessRecord mPreviousProcess;
579
580    /**
581     * The time at which the previous process was last visible.
582     */
583    long mPreviousProcessVisibleTime;
584
585    /**
586     * Which uses have been started, so are allowed to run code.
587     */
588    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
589
590    /**
591     * LRU list of history of current users.  Most recently current is at the end.
592     */
593    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
594
595    /**
596     * Constant array of the users that are currently started.
597     */
598    int[] mStartedUserArray = new int[] { 0 };
599
600    /**
601     * Registered observers of the user switching mechanics.
602     */
603    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
604            = new RemoteCallbackList<IUserSwitchObserver>();
605
606    /**
607     * Currently active user switch.
608     */
609    Object mCurUserSwitchCallback;
610
611    /**
612     * Packages that the user has asked to have run in screen size
613     * compatibility mode instead of filling the screen.
614     */
615    final CompatModePackages mCompatModePackages;
616
617    /**
618     * Set of IntentSenderRecord objects that are currently active.
619     */
620    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
621            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
622
623    /**
624     * Fingerprints (hashCode()) of stack traces that we've
625     * already logged DropBox entries for.  Guarded by itself.  If
626     * something (rogue user app) forces this over
627     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
628     */
629    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
630    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
631
632    /**
633     * Strict Mode background batched logging state.
634     *
635     * The string buffer is guarded by itself, and its lock is also
636     * used to determine if another batched write is already
637     * in-flight.
638     */
639    private final StringBuilder mStrictModeBuffer = new StringBuilder();
640
641    /**
642     * Keeps track of all IIntentReceivers that have been registered for
643     * broadcasts.  Hash keys are the receiver IBinder, hash value is
644     * a ReceiverList.
645     */
646    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
647            new HashMap<IBinder, ReceiverList>();
648
649    /**
650     * Resolver for broadcast intents to registered receivers.
651     * Holds BroadcastFilter (subclass of IntentFilter).
652     */
653    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
654            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
655        @Override
656        protected boolean allowFilterResult(
657                BroadcastFilter filter, List<BroadcastFilter> dest) {
658            IBinder target = filter.receiverList.receiver.asBinder();
659            for (int i=dest.size()-1; i>=0; i--) {
660                if (dest.get(i).receiverList.receiver.asBinder() == target) {
661                    return false;
662                }
663            }
664            return true;
665        }
666
667        @Override
668        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
669            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
670                    || userId == filter.owningUserId) {
671                return super.newResult(filter, match, userId);
672            }
673            return null;
674        }
675
676        @Override
677        protected BroadcastFilter[] newArray(int size) {
678            return new BroadcastFilter[size];
679        }
680
681        @Override
682        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
683            return packageName.equals(filter.packageName);
684        }
685    };
686
687    /**
688     * State of all active sticky broadcasts per user.  Keys are the action of the
689     * sticky Intent, values are an ArrayList of all broadcasted intents with
690     * that action (which should usually be one).  The SparseArray is keyed
691     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
692     * for stickies that are sent to all users.
693     */
694    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
695            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
696
697    final ActiveServices mServices;
698
699    /**
700     * Backup/restore process management
701     */
702    String mBackupAppName = null;
703    BackupRecord mBackupTarget = null;
704
705    final ProviderMap mProviderMap;
706
707    /**
708     * List of content providers who have clients waiting for them.  The
709     * application is currently being launched and the provider will be
710     * removed from this list once it is published.
711     */
712    final ArrayList<ContentProviderRecord> mLaunchingProviders
713            = new ArrayList<ContentProviderRecord>();
714
715    /**
716     * File storing persisted {@link #mGrantedUriPermissions}.
717     */
718    private final AtomicFile mGrantFile;
719
720    /** XML constants used in {@link #mGrantFile} */
721    private static final String TAG_URI_GRANTS = "uri-grants";
722    private static final String TAG_URI_GRANT = "uri-grant";
723    private static final String ATTR_USER_HANDLE = "userHandle";
724    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
725    private static final String ATTR_TARGET_USER_ID = "targetUserId";
726    private static final String ATTR_SOURCE_PKG = "sourcePkg";
727    private static final String ATTR_TARGET_PKG = "targetPkg";
728    private static final String ATTR_URI = "uri";
729    private static final String ATTR_MODE_FLAGS = "modeFlags";
730    private static final String ATTR_CREATED_TIME = "createdTime";
731    private static final String ATTR_PREFIX = "prefix";
732
733    /**
734     * Global set of specific {@link Uri} permissions that have been granted.
735     * This optimized lookup structure maps from {@link UriPermission#targetUid}
736     * to {@link UriPermission#uri} to {@link UriPermission}.
737     */
738    @GuardedBy("this")
739    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
740            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
741
742    public static class GrantUri {
743        public final int sourceUserId;
744        public final Uri uri;
745        public boolean prefix;
746
747        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
748            this.sourceUserId = sourceUserId;
749            this.uri = uri;
750            this.prefix = prefix;
751        }
752
753        @Override
754        public int hashCode() {
755            return toString().hashCode();
756        }
757
758        @Override
759        public boolean equals(Object o) {
760            if (o instanceof GrantUri) {
761                GrantUri other = (GrantUri) o;
762                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
763                        && prefix == other.prefix;
764            }
765            return false;
766        }
767
768        @Override
769        public String toString() {
770            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
771            if (prefix) result += " [prefix]";
772            return result;
773        }
774
775        public String toSafeString() {
776            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
777            if (prefix) result += " [prefix]";
778            return result;
779        }
780
781        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
782            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
783                    ContentProvider.getUriWithoutUserId(uri), false);
784        }
785    }
786
787    CoreSettingsObserver mCoreSettingsObserver;
788
789    /**
790     * Thread-local storage used to carry caller permissions over through
791     * indirect content-provider access.
792     */
793    private class Identity {
794        public int pid;
795        public int uid;
796
797        Identity(int _pid, int _uid) {
798            pid = _pid;
799            uid = _uid;
800        }
801    }
802
803    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
804
805    /**
806     * All information we have collected about the runtime performance of
807     * any user id that can impact battery performance.
808     */
809    final BatteryStatsService mBatteryStatsService;
810
811    /**
812     * Information about component usage
813     */
814    final UsageStatsService mUsageStatsService;
815
816    /**
817     * Information about and control over application operations
818     */
819    final AppOpsService mAppOpsService;
820
821    /**
822     * Current configuration information.  HistoryRecord objects are given
823     * a reference to this object to indicate which configuration they are
824     * currently running in, so this object must be kept immutable.
825     */
826    Configuration mConfiguration = new Configuration();
827
828    /**
829     * Current sequencing integer of the configuration, for skipping old
830     * configurations.
831     */
832    int mConfigurationSeq = 0;
833
834    /**
835     * Hardware-reported OpenGLES version.
836     */
837    final int GL_ES_VERSION;
838
839    /**
840     * List of initialization arguments to pass to all processes when binding applications to them.
841     * For example, references to the commonly used services.
842     */
843    HashMap<String, IBinder> mAppBindArgs;
844
845    /**
846     * Temporary to avoid allocations.  Protected by main lock.
847     */
848    final StringBuilder mStringBuilder = new StringBuilder(256);
849
850    /**
851     * Used to control how we initialize the service.
852     */
853    ComponentName mTopComponent;
854    String mTopAction = Intent.ACTION_MAIN;
855    String mTopData;
856    boolean mProcessesReady = false;
857    boolean mSystemReady = false;
858    boolean mBooting = false;
859    boolean mWaitingUpdate = false;
860    boolean mDidUpdate = false;
861    boolean mOnBattery = false;
862    boolean mLaunchWarningShown = false;
863
864    Context mContext;
865
866    int mFactoryTest;
867
868    boolean mCheckedForSetup;
869
870    /**
871     * The time at which we will allow normal application switches again,
872     * after a call to {@link #stopAppSwitches()}.
873     */
874    long mAppSwitchesAllowedTime;
875
876    /**
877     * This is set to true after the first switch after mAppSwitchesAllowedTime
878     * is set; any switches after that will clear the time.
879     */
880    boolean mDidAppSwitch;
881
882    /**
883     * Last time (in realtime) at which we checked for power usage.
884     */
885    long mLastPowerCheckRealtime;
886
887    /**
888     * Last time (in uptime) at which we checked for power usage.
889     */
890    long mLastPowerCheckUptime;
891
892    /**
893     * Set while we are wanting to sleep, to prevent any
894     * activities from being started/resumed.
895     */
896    private boolean mSleeping = false;
897
898    /**
899     * Set while we are running a voice interaction.  This overrides
900     * sleeping while it is active.
901     */
902    private boolean mRunningVoice = false;
903
904    /**
905     * State of external calls telling us if the device is asleep.
906     */
907    private boolean mWentToSleep = false;
908
909    /**
910     * State of external call telling us if the lock screen is shown.
911     */
912    private boolean mLockScreenShown = false;
913
914    /**
915     * Set if we are shutting down the system, similar to sleeping.
916     */
917    boolean mShuttingDown = false;
918
919    /**
920     * Current sequence id for oom_adj computation traversal.
921     */
922    int mAdjSeq = 0;
923
924    /**
925     * Current sequence id for process LRU updating.
926     */
927    int mLruSeq = 0;
928
929    /**
930     * Keep track of the non-cached/empty process we last found, to help
931     * determine how to distribute cached/empty processes next time.
932     */
933    int mNumNonCachedProcs = 0;
934
935    /**
936     * Keep track of the number of cached hidden procs, to balance oom adj
937     * distribution between those and empty procs.
938     */
939    int mNumCachedHiddenProcs = 0;
940
941    /**
942     * Keep track of the number of service processes we last found, to
943     * determine on the next iteration which should be B services.
944     */
945    int mNumServiceProcs = 0;
946    int mNewNumAServiceProcs = 0;
947    int mNewNumServiceProcs = 0;
948
949    /**
950     * Allow the current computed overall memory level of the system to go down?
951     * This is set to false when we are killing processes for reasons other than
952     * memory management, so that the now smaller process list will not be taken as
953     * an indication that memory is tighter.
954     */
955    boolean mAllowLowerMemLevel = false;
956
957    /**
958     * The last computed memory level, for holding when we are in a state that
959     * processes are going away for other reasons.
960     */
961    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
962
963    /**
964     * The last total number of process we have, to determine if changes actually look
965     * like a shrinking number of process due to lower RAM.
966     */
967    int mLastNumProcesses;
968
969    /**
970     * The uptime of the last time we performed idle maintenance.
971     */
972    long mLastIdleTime = SystemClock.uptimeMillis();
973
974    /**
975     * Total time spent with RAM that has been added in the past since the last idle time.
976     */
977    long mLowRamTimeSinceLastIdle = 0;
978
979    /**
980     * If RAM is currently low, when that horrible situation started.
981     */
982    long mLowRamStartTime = 0;
983
984    /**
985     * For reporting to battery stats the current top application.
986     */
987    private String mCurResumedPackage = null;
988    private int mCurResumedUid = -1;
989
990    /**
991     * For reporting to battery stats the apps currently running foreground
992     * service.  The ProcessMap is package/uid tuples; each of these contain
993     * an array of the currently foreground processes.
994     */
995    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
996            = new ProcessMap<ArrayList<ProcessRecord>>();
997
998    /**
999     * This is set if we had to do a delayed dexopt of an app before launching
1000     * it, to increase the ANR timeouts in that case.
1001     */
1002    boolean mDidDexOpt;
1003
1004    /**
1005     * Set if the systemServer made a call to enterSafeMode.
1006     */
1007    boolean mSafeMode;
1008
1009    String mDebugApp = null;
1010    boolean mWaitForDebugger = false;
1011    boolean mDebugTransient = false;
1012    String mOrigDebugApp = null;
1013    boolean mOrigWaitForDebugger = false;
1014    boolean mAlwaysFinishActivities = false;
1015    IActivityController mController = null;
1016    String mProfileApp = null;
1017    ProcessRecord mProfileProc = null;
1018    String mProfileFile;
1019    ParcelFileDescriptor mProfileFd;
1020    int mProfileType = 0;
1021    boolean mAutoStopProfiler = false;
1022    String mOpenGlTraceApp = null;
1023
1024    static class ProcessChangeItem {
1025        static final int CHANGE_ACTIVITIES = 1<<0;
1026        static final int CHANGE_PROCESS_STATE = 1<<1;
1027        int changes;
1028        int uid;
1029        int pid;
1030        int processState;
1031        boolean foregroundActivities;
1032    }
1033
1034    final RemoteCallbackList<IProcessObserver> mProcessObservers
1035            = new RemoteCallbackList<IProcessObserver>();
1036    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1037
1038    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1039            = new ArrayList<ProcessChangeItem>();
1040    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1041            = new ArrayList<ProcessChangeItem>();
1042
1043    /**
1044     * Runtime CPU use collection thread.  This object's lock is used to
1045     * protect all related state.
1046     */
1047    final Thread mProcessCpuThread;
1048
1049    /**
1050     * Used to collect process stats when showing not responding dialog.
1051     * Protected by mProcessCpuThread.
1052     */
1053    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1054            MONITOR_THREAD_CPU_USAGE);
1055    final AtomicLong mLastCpuTime = new AtomicLong(0);
1056    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1057
1058    long mLastWriteTime = 0;
1059
1060    /**
1061     * Used to retain an update lock when the foreground activity is in
1062     * immersive mode.
1063     */
1064    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1065
1066    /**
1067     * Set to true after the system has finished booting.
1068     */
1069    boolean mBooted = false;
1070
1071    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1072    int mProcessLimitOverride = -1;
1073
1074    WindowManagerService mWindowManager;
1075
1076    final ActivityThread mSystemThread;
1077
1078    int mCurrentUserId = 0;
1079    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1080    private UserManagerService mUserManager;
1081
1082    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1083        final ProcessRecord mApp;
1084        final int mPid;
1085        final IApplicationThread mAppThread;
1086
1087        AppDeathRecipient(ProcessRecord app, int pid,
1088                IApplicationThread thread) {
1089            if (localLOGV) Slog.v(
1090                TAG, "New death recipient " + this
1091                + " for thread " + thread.asBinder());
1092            mApp = app;
1093            mPid = pid;
1094            mAppThread = thread;
1095        }
1096
1097        @Override
1098        public void binderDied() {
1099            if (localLOGV) Slog.v(
1100                TAG, "Death received in " + this
1101                + " for thread " + mAppThread.asBinder());
1102            synchronized(ActivityManagerService.this) {
1103                appDiedLocked(mApp, mPid, mAppThread);
1104            }
1105        }
1106    }
1107
1108    static final int SHOW_ERROR_MSG = 1;
1109    static final int SHOW_NOT_RESPONDING_MSG = 2;
1110    static final int SHOW_FACTORY_ERROR_MSG = 3;
1111    static final int UPDATE_CONFIGURATION_MSG = 4;
1112    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1113    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1114    static final int SERVICE_TIMEOUT_MSG = 12;
1115    static final int UPDATE_TIME_ZONE = 13;
1116    static final int SHOW_UID_ERROR_MSG = 14;
1117    static final int IM_FEELING_LUCKY_MSG = 15;
1118    static final int PROC_START_TIMEOUT_MSG = 20;
1119    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1120    static final int KILL_APPLICATION_MSG = 22;
1121    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1122    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1123    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1124    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1125    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1126    static final int CLEAR_DNS_CACHE_MSG = 28;
1127    static final int UPDATE_HTTP_PROXY_MSG = 29;
1128    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1129    static final int DISPATCH_PROCESSES_CHANGED = 31;
1130    static final int DISPATCH_PROCESS_DIED = 32;
1131    static final int REPORT_MEM_USAGE_MSG = 33;
1132    static final int REPORT_USER_SWITCH_MSG = 34;
1133    static final int CONTINUE_USER_SWITCH_MSG = 35;
1134    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1135    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1136    static final int PERSIST_URI_GRANTS_MSG = 38;
1137    static final int REQUEST_ALL_PSS_MSG = 39;
1138    static final int START_PROFILES_MSG = 40;
1139    static final int UPDATE_TIME = 41;
1140    static final int SYSTEM_USER_START_MSG = 42;
1141    static final int SYSTEM_USER_CURRENT_MSG = 43;
1142
1143    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1144    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1145    static final int FIRST_COMPAT_MODE_MSG = 300;
1146    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1147
1148    AlertDialog mUidAlert;
1149    CompatModeDialog mCompatModeDialog;
1150    long mLastMemUsageReportTime = 0;
1151
1152    /**
1153     * Flag whether the current user is a "monkey", i.e. whether
1154     * the UI is driven by a UI automation tool.
1155     */
1156    private boolean mUserIsMonkey;
1157
1158    final ServiceThread mHandlerThread;
1159    final MainHandler mHandler;
1160
1161    final class MainHandler extends Handler {
1162        public MainHandler(Looper looper) {
1163            super(looper, null, true);
1164        }
1165
1166        @Override
1167        public void handleMessage(Message msg) {
1168            switch (msg.what) {
1169            case SHOW_ERROR_MSG: {
1170                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1171                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1172                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1173                synchronized (ActivityManagerService.this) {
1174                    ProcessRecord proc = (ProcessRecord)data.get("app");
1175                    AppErrorResult res = (AppErrorResult) data.get("result");
1176                    if (proc != null && proc.crashDialog != null) {
1177                        Slog.e(TAG, "App already has crash dialog: " + proc);
1178                        if (res != null) {
1179                            res.set(0);
1180                        }
1181                        return;
1182                    }
1183                    if (!showBackground && UserHandle.getAppId(proc.uid)
1184                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1185                            && proc.pid != MY_PID) {
1186                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1187                        if (res != null) {
1188                            res.set(0);
1189                        }
1190                        return;
1191                    }
1192                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1193                        Dialog d = new AppErrorDialog(mContext,
1194                                ActivityManagerService.this, res, proc);
1195                        d.show();
1196                        proc.crashDialog = d;
1197                    } else {
1198                        // The device is asleep, so just pretend that the user
1199                        // saw a crash dialog and hit "force quit".
1200                        if (res != null) {
1201                            res.set(0);
1202                        }
1203                    }
1204                }
1205
1206                ensureBootCompleted();
1207            } break;
1208            case SHOW_NOT_RESPONDING_MSG: {
1209                synchronized (ActivityManagerService.this) {
1210                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1211                    ProcessRecord proc = (ProcessRecord)data.get("app");
1212                    if (proc != null && proc.anrDialog != null) {
1213                        Slog.e(TAG, "App already has anr dialog: " + proc);
1214                        return;
1215                    }
1216
1217                    Intent intent = new Intent("android.intent.action.ANR");
1218                    if (!mProcessesReady) {
1219                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1220                                | Intent.FLAG_RECEIVER_FOREGROUND);
1221                    }
1222                    broadcastIntentLocked(null, null, intent,
1223                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1224                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1225
1226                    if (mShowDialogs) {
1227                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1228                                mContext, proc, (ActivityRecord)data.get("activity"),
1229                                msg.arg1 != 0);
1230                        d.show();
1231                        proc.anrDialog = d;
1232                    } else {
1233                        // Just kill the app if there is no dialog to be shown.
1234                        killAppAtUsersRequest(proc, null);
1235                    }
1236                }
1237
1238                ensureBootCompleted();
1239            } break;
1240            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1241                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1242                synchronized (ActivityManagerService.this) {
1243                    ProcessRecord proc = (ProcessRecord) data.get("app");
1244                    if (proc == null) {
1245                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1246                        break;
1247                    }
1248                    if (proc.crashDialog != null) {
1249                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1250                        return;
1251                    }
1252                    AppErrorResult res = (AppErrorResult) data.get("result");
1253                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1254                        Dialog d = new StrictModeViolationDialog(mContext,
1255                                ActivityManagerService.this, res, proc);
1256                        d.show();
1257                        proc.crashDialog = d;
1258                    } else {
1259                        // The device is asleep, so just pretend that the user
1260                        // saw a crash dialog and hit "force quit".
1261                        res.set(0);
1262                    }
1263                }
1264                ensureBootCompleted();
1265            } break;
1266            case SHOW_FACTORY_ERROR_MSG: {
1267                Dialog d = new FactoryErrorDialog(
1268                    mContext, msg.getData().getCharSequence("msg"));
1269                d.show();
1270                ensureBootCompleted();
1271            } break;
1272            case UPDATE_CONFIGURATION_MSG: {
1273                final ContentResolver resolver = mContext.getContentResolver();
1274                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1275            } break;
1276            case GC_BACKGROUND_PROCESSES_MSG: {
1277                synchronized (ActivityManagerService.this) {
1278                    performAppGcsIfAppropriateLocked();
1279                }
1280            } break;
1281            case WAIT_FOR_DEBUGGER_MSG: {
1282                synchronized (ActivityManagerService.this) {
1283                    ProcessRecord app = (ProcessRecord)msg.obj;
1284                    if (msg.arg1 != 0) {
1285                        if (!app.waitedForDebugger) {
1286                            Dialog d = new AppWaitingForDebuggerDialog(
1287                                    ActivityManagerService.this,
1288                                    mContext, app);
1289                            app.waitDialog = d;
1290                            app.waitedForDebugger = true;
1291                            d.show();
1292                        }
1293                    } else {
1294                        if (app.waitDialog != null) {
1295                            app.waitDialog.dismiss();
1296                            app.waitDialog = null;
1297                        }
1298                    }
1299                }
1300            } break;
1301            case SERVICE_TIMEOUT_MSG: {
1302                if (mDidDexOpt) {
1303                    mDidDexOpt = false;
1304                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1305                    nmsg.obj = msg.obj;
1306                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1307                    return;
1308                }
1309                mServices.serviceTimeout((ProcessRecord)msg.obj);
1310            } break;
1311            case UPDATE_TIME_ZONE: {
1312                synchronized (ActivityManagerService.this) {
1313                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1314                        ProcessRecord r = mLruProcesses.get(i);
1315                        if (r.thread != null) {
1316                            try {
1317                                r.thread.updateTimeZone();
1318                            } catch (RemoteException ex) {
1319                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1320                            }
1321                        }
1322                    }
1323                }
1324            } break;
1325            case CLEAR_DNS_CACHE_MSG: {
1326                synchronized (ActivityManagerService.this) {
1327                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1328                        ProcessRecord r = mLruProcesses.get(i);
1329                        if (r.thread != null) {
1330                            try {
1331                                r.thread.clearDnsCache();
1332                            } catch (RemoteException ex) {
1333                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1334                            }
1335                        }
1336                    }
1337                }
1338            } break;
1339            case UPDATE_HTTP_PROXY_MSG: {
1340                ProxyInfo proxy = (ProxyInfo)msg.obj;
1341                String host = "";
1342                String port = "";
1343                String exclList = "";
1344                String pacFileUrl = null;
1345                if (proxy != null) {
1346                    host = proxy.getHost();
1347                    port = Integer.toString(proxy.getPort());
1348                    exclList = proxy.getExclusionListAsString();
1349                    pacFileUrl = proxy.getPacFileUrl().toString();
1350                }
1351                synchronized (ActivityManagerService.this) {
1352                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1353                        ProcessRecord r = mLruProcesses.get(i);
1354                        if (r.thread != null) {
1355                            try {
1356                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1357                            } catch (RemoteException ex) {
1358                                Slog.w(TAG, "Failed to update http proxy for: " +
1359                                        r.info.processName);
1360                            }
1361                        }
1362                    }
1363                }
1364            } break;
1365            case SHOW_UID_ERROR_MSG: {
1366                String title = "System UIDs Inconsistent";
1367                String text = "UIDs on the system are inconsistent, you need to wipe your"
1368                        + " data partition or your device will be unstable.";
1369                Log.e(TAG, title + ": " + text);
1370                if (mShowDialogs) {
1371                    // XXX This is a temporary dialog, no need to localize.
1372                    AlertDialog d = new BaseErrorDialog(mContext);
1373                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1374                    d.setCancelable(false);
1375                    d.setTitle(title);
1376                    d.setMessage(text);
1377                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1378                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1379                    mUidAlert = d;
1380                    d.show();
1381                }
1382            } break;
1383            case IM_FEELING_LUCKY_MSG: {
1384                if (mUidAlert != null) {
1385                    mUidAlert.dismiss();
1386                    mUidAlert = null;
1387                }
1388            } break;
1389            case PROC_START_TIMEOUT_MSG: {
1390                if (mDidDexOpt) {
1391                    mDidDexOpt = false;
1392                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1393                    nmsg.obj = msg.obj;
1394                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1395                    return;
1396                }
1397                ProcessRecord app = (ProcessRecord)msg.obj;
1398                synchronized (ActivityManagerService.this) {
1399                    processStartTimedOutLocked(app);
1400                }
1401            } break;
1402            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1403                synchronized (ActivityManagerService.this) {
1404                    doPendingActivityLaunchesLocked(true);
1405                }
1406            } break;
1407            case KILL_APPLICATION_MSG: {
1408                synchronized (ActivityManagerService.this) {
1409                    int appid = msg.arg1;
1410                    boolean restart = (msg.arg2 == 1);
1411                    Bundle bundle = (Bundle)msg.obj;
1412                    String pkg = bundle.getString("pkg");
1413                    String reason = bundle.getString("reason");
1414                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1415                            false, UserHandle.USER_ALL, reason);
1416                }
1417            } break;
1418            case FINALIZE_PENDING_INTENT_MSG: {
1419                ((PendingIntentRecord)msg.obj).completeFinalize();
1420            } break;
1421            case POST_HEAVY_NOTIFICATION_MSG: {
1422                INotificationManager inm = NotificationManager.getService();
1423                if (inm == null) {
1424                    return;
1425                }
1426
1427                ActivityRecord root = (ActivityRecord)msg.obj;
1428                ProcessRecord process = root.app;
1429                if (process == null) {
1430                    return;
1431                }
1432
1433                try {
1434                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1435                    String text = mContext.getString(R.string.heavy_weight_notification,
1436                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1437                    Notification notification = new Notification();
1438                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1439                    notification.when = 0;
1440                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1441                    notification.tickerText = text;
1442                    notification.defaults = 0; // please be quiet
1443                    notification.sound = null;
1444                    notification.vibrate = null;
1445                    notification.setLatestEventInfo(context, text,
1446                            mContext.getText(R.string.heavy_weight_notification_detail),
1447                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1448                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1449                                    new UserHandle(root.userId)));
1450
1451                    try {
1452                        int[] outId = new int[1];
1453                        inm.enqueueNotificationWithTag("android", "android", null,
1454                                R.string.heavy_weight_notification,
1455                                notification, outId, root.userId);
1456                    } catch (RuntimeException e) {
1457                        Slog.w(ActivityManagerService.TAG,
1458                                "Error showing notification for heavy-weight app", e);
1459                    } catch (RemoteException e) {
1460                    }
1461                } catch (NameNotFoundException e) {
1462                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1463                }
1464            } break;
1465            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1466                INotificationManager inm = NotificationManager.getService();
1467                if (inm == null) {
1468                    return;
1469                }
1470                try {
1471                    inm.cancelNotificationWithTag("android", null,
1472                            R.string.heavy_weight_notification,  msg.arg1);
1473                } catch (RuntimeException e) {
1474                    Slog.w(ActivityManagerService.TAG,
1475                            "Error canceling notification for service", e);
1476                } catch (RemoteException e) {
1477                }
1478            } break;
1479            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1480                synchronized (ActivityManagerService.this) {
1481                    checkExcessivePowerUsageLocked(true);
1482                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1483                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1484                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1485                }
1486            } break;
1487            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1488                synchronized (ActivityManagerService.this) {
1489                    ActivityRecord ar = (ActivityRecord)msg.obj;
1490                    if (mCompatModeDialog != null) {
1491                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1492                                ar.info.applicationInfo.packageName)) {
1493                            return;
1494                        }
1495                        mCompatModeDialog.dismiss();
1496                        mCompatModeDialog = null;
1497                    }
1498                    if (ar != null && false) {
1499                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1500                                ar.packageName)) {
1501                            int mode = mCompatModePackages.computeCompatModeLocked(
1502                                    ar.info.applicationInfo);
1503                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1504                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1505                                mCompatModeDialog = new CompatModeDialog(
1506                                        ActivityManagerService.this, mContext,
1507                                        ar.info.applicationInfo);
1508                                mCompatModeDialog.show();
1509                            }
1510                        }
1511                    }
1512                }
1513                break;
1514            }
1515            case DISPATCH_PROCESSES_CHANGED: {
1516                dispatchProcessesChanged();
1517                break;
1518            }
1519            case DISPATCH_PROCESS_DIED: {
1520                final int pid = msg.arg1;
1521                final int uid = msg.arg2;
1522                dispatchProcessDied(pid, uid);
1523                break;
1524            }
1525            case REPORT_MEM_USAGE_MSG: {
1526                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1527                Thread thread = new Thread() {
1528                    @Override public void run() {
1529                        final SparseArray<ProcessMemInfo> infoMap
1530                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1531                        for (int i=0, N=memInfos.size(); i<N; i++) {
1532                            ProcessMemInfo mi = memInfos.get(i);
1533                            infoMap.put(mi.pid, mi);
1534                        }
1535                        updateCpuStatsNow();
1536                        synchronized (mProcessCpuThread) {
1537                            final int N = mProcessCpuTracker.countStats();
1538                            for (int i=0; i<N; i++) {
1539                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1540                                if (st.vsize > 0) {
1541                                    long pss = Debug.getPss(st.pid, null);
1542                                    if (pss > 0) {
1543                                        if (infoMap.indexOfKey(st.pid) < 0) {
1544                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1545                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1546                                            mi.pss = pss;
1547                                            memInfos.add(mi);
1548                                        }
1549                                    }
1550                                }
1551                            }
1552                        }
1553
1554                        long totalPss = 0;
1555                        for (int i=0, N=memInfos.size(); i<N; i++) {
1556                            ProcessMemInfo mi = memInfos.get(i);
1557                            if (mi.pss == 0) {
1558                                mi.pss = Debug.getPss(mi.pid, null);
1559                            }
1560                            totalPss += mi.pss;
1561                        }
1562                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1563                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1564                                if (lhs.oomAdj != rhs.oomAdj) {
1565                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1566                                }
1567                                if (lhs.pss != rhs.pss) {
1568                                    return lhs.pss < rhs.pss ? 1 : -1;
1569                                }
1570                                return 0;
1571                            }
1572                        });
1573
1574                        StringBuilder tag = new StringBuilder(128);
1575                        StringBuilder stack = new StringBuilder(128);
1576                        tag.append("Low on memory -- ");
1577                        appendMemBucket(tag, totalPss, "total", false);
1578                        appendMemBucket(stack, totalPss, "total", true);
1579
1580                        StringBuilder logBuilder = new StringBuilder(1024);
1581                        logBuilder.append("Low on memory:\n");
1582
1583                        boolean firstLine = true;
1584                        int lastOomAdj = Integer.MIN_VALUE;
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587
1588                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1589                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1590                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1591                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1592                                if (lastOomAdj != mi.oomAdj) {
1593                                    lastOomAdj = mi.oomAdj;
1594                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1595                                        tag.append(" / ");
1596                                    }
1597                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1598                                        if (firstLine) {
1599                                            stack.append(":");
1600                                            firstLine = false;
1601                                        }
1602                                        stack.append("\n\t at ");
1603                                    } else {
1604                                        stack.append("$");
1605                                    }
1606                                } else {
1607                                    tag.append(" ");
1608                                    stack.append("$");
1609                                }
1610                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1611                                    appendMemBucket(tag, mi.pss, mi.name, false);
1612                                }
1613                                appendMemBucket(stack, mi.pss, mi.name, true);
1614                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1615                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1616                                    stack.append("(");
1617                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1618                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1619                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1620                                            stack.append(":");
1621                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1622                                        }
1623                                    }
1624                                    stack.append(")");
1625                                }
1626                            }
1627
1628                            logBuilder.append("  ");
1629                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1630                            logBuilder.append(' ');
1631                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1632                            logBuilder.append(' ');
1633                            ProcessList.appendRamKb(logBuilder, mi.pss);
1634                            logBuilder.append(" kB: ");
1635                            logBuilder.append(mi.name);
1636                            logBuilder.append(" (");
1637                            logBuilder.append(mi.pid);
1638                            logBuilder.append(") ");
1639                            logBuilder.append(mi.adjType);
1640                            logBuilder.append('\n');
1641                            if (mi.adjReason != null) {
1642                                logBuilder.append("                      ");
1643                                logBuilder.append(mi.adjReason);
1644                                logBuilder.append('\n');
1645                            }
1646                        }
1647
1648                        logBuilder.append("           ");
1649                        ProcessList.appendRamKb(logBuilder, totalPss);
1650                        logBuilder.append(" kB: TOTAL\n");
1651
1652                        long[] infos = new long[Debug.MEMINFO_COUNT];
1653                        Debug.getMemInfo(infos);
1654                        logBuilder.append("  MemInfo: ");
1655                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1656                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1657                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1658                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1659                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1660                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1661                            logBuilder.append("  ZRAM: ");
1662                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1663                            logBuilder.append(" kB RAM, ");
1664                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1665                            logBuilder.append(" kB swap total, ");
1666                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1667                            logBuilder.append(" kB swap free\n");
1668                        }
1669                        Slog.i(TAG, logBuilder.toString());
1670
1671                        StringBuilder dropBuilder = new StringBuilder(1024);
1672                        /*
1673                        StringWriter oomSw = new StringWriter();
1674                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1675                        StringWriter catSw = new StringWriter();
1676                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1677                        String[] emptyArgs = new String[] { };
1678                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1679                        oomPw.flush();
1680                        String oomString = oomSw.toString();
1681                        */
1682                        dropBuilder.append(stack);
1683                        dropBuilder.append('\n');
1684                        dropBuilder.append('\n');
1685                        dropBuilder.append(logBuilder);
1686                        dropBuilder.append('\n');
1687                        /*
1688                        dropBuilder.append(oomString);
1689                        dropBuilder.append('\n');
1690                        */
1691                        StringWriter catSw = new StringWriter();
1692                        synchronized (ActivityManagerService.this) {
1693                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1694                            String[] emptyArgs = new String[] { };
1695                            catPw.println();
1696                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1697                            catPw.println();
1698                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1699                                    false, false, null);
1700                            catPw.println();
1701                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1702                            catPw.flush();
1703                        }
1704                        dropBuilder.append(catSw.toString());
1705                        addErrorToDropBox("lowmem", null, "system_server", null,
1706                                null, tag.toString(), dropBuilder.toString(), null, null);
1707                        //Slog.i(TAG, "Sent to dropbox:");
1708                        //Slog.i(TAG, dropBuilder.toString());
1709                        synchronized (ActivityManagerService.this) {
1710                            long now = SystemClock.uptimeMillis();
1711                            if (mLastMemUsageReportTime < now) {
1712                                mLastMemUsageReportTime = now;
1713                            }
1714                        }
1715                    }
1716                };
1717                thread.start();
1718                break;
1719            }
1720            case REPORT_USER_SWITCH_MSG: {
1721                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1722                break;
1723            }
1724            case CONTINUE_USER_SWITCH_MSG: {
1725                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1726                break;
1727            }
1728            case USER_SWITCH_TIMEOUT_MSG: {
1729                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1730                break;
1731            }
1732            case IMMERSIVE_MODE_LOCK_MSG: {
1733                final boolean nextState = (msg.arg1 != 0);
1734                if (mUpdateLock.isHeld() != nextState) {
1735                    if (DEBUG_IMMERSIVE) {
1736                        final ActivityRecord r = (ActivityRecord) msg.obj;
1737                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1738                    }
1739                    if (nextState) {
1740                        mUpdateLock.acquire();
1741                    } else {
1742                        mUpdateLock.release();
1743                    }
1744                }
1745                break;
1746            }
1747            case PERSIST_URI_GRANTS_MSG: {
1748                writeGrantedUriPermissions();
1749                break;
1750            }
1751            case REQUEST_ALL_PSS_MSG: {
1752                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1753                break;
1754            }
1755            case START_PROFILES_MSG: {
1756                synchronized (ActivityManagerService.this) {
1757                    startProfilesLocked();
1758                }
1759                break;
1760            }
1761            case UPDATE_TIME: {
1762                synchronized (ActivityManagerService.this) {
1763                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1764                        ProcessRecord r = mLruProcesses.get(i);
1765                        if (r.thread != null) {
1766                            try {
1767                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1768                            } catch (RemoteException ex) {
1769                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1770                            }
1771                        }
1772                    }
1773                }
1774                break;
1775            }
1776            case SYSTEM_USER_START_MSG: {
1777                mSystemServiceManager.startUser(msg.arg1);
1778                break;
1779            }
1780            case SYSTEM_USER_CURRENT_MSG: {
1781                mSystemServiceManager.switchUser(msg.arg1);
1782                break;
1783            }
1784            }
1785        }
1786    };
1787
1788    static final int COLLECT_PSS_BG_MSG = 1;
1789
1790    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1791        @Override
1792        public void handleMessage(Message msg) {
1793            switch (msg.what) {
1794            case COLLECT_PSS_BG_MSG: {
1795                int i=0, num=0;
1796                long start = SystemClock.uptimeMillis();
1797                long[] tmp = new long[1];
1798                do {
1799                    ProcessRecord proc;
1800                    int procState;
1801                    int pid;
1802                    synchronized (ActivityManagerService.this) {
1803                        if (i >= mPendingPssProcesses.size()) {
1804                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1805                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1806                            mPendingPssProcesses.clear();
1807                            return;
1808                        }
1809                        proc = mPendingPssProcesses.get(i);
1810                        procState = proc.pssProcState;
1811                        if (proc.thread != null && procState == proc.setProcState) {
1812                            pid = proc.pid;
1813                        } else {
1814                            proc = null;
1815                            pid = 0;
1816                        }
1817                        i++;
1818                    }
1819                    if (proc != null) {
1820                        long pss = Debug.getPss(pid, tmp);
1821                        synchronized (ActivityManagerService.this) {
1822                            if (proc.thread != null && proc.setProcState == procState
1823                                    && proc.pid == pid) {
1824                                num++;
1825                                proc.lastPssTime = SystemClock.uptimeMillis();
1826                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1827                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1828                                        + ": " + pss + " lastPss=" + proc.lastPss
1829                                        + " state=" + ProcessList.makeProcStateString(procState));
1830                                if (proc.initialIdlePss == 0) {
1831                                    proc.initialIdlePss = pss;
1832                                }
1833                                proc.lastPss = pss;
1834                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1835                                    proc.lastCachedPss = pss;
1836                                }
1837                            }
1838                        }
1839                    }
1840                } while (true);
1841            }
1842            }
1843        }
1844    };
1845
1846    /**
1847     * Monitor for package changes and update our internal state.
1848     */
1849    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1850        @Override
1851        public void onPackageRemoved(String packageName, int uid) {
1852            // Remove all tasks with activities in the specified package from the list of recent tasks
1853            synchronized (ActivityManagerService.this) {
1854                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1855                    TaskRecord tr = mRecentTasks.get(i);
1856                    ComponentName cn = tr.intent.getComponent();
1857                    if (cn != null && cn.getPackageName().equals(packageName)) {
1858                        // If the package name matches, remove the task and kill the process
1859                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1860                    }
1861                }
1862            }
1863        }
1864
1865        @Override
1866        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1867            onPackageModified(packageName);
1868            return true;
1869        }
1870
1871        @Override
1872        public void onPackageModified(String packageName) {
1873            final PackageManager pm = mContext.getPackageManager();
1874            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1875                    new ArrayList<Pair<Intent, Integer>>();
1876            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1877            // Copy the list of recent tasks so that we don't hold onto the lock on
1878            // ActivityManagerService for long periods while checking if components exist.
1879            synchronized (ActivityManagerService.this) {
1880                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1881                    TaskRecord tr = mRecentTasks.get(i);
1882                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1883                }
1884            }
1885            // Check the recent tasks and filter out all tasks with components that no longer exist.
1886            Intent tmpI = new Intent();
1887            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1888                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1889                ComponentName cn = p.first.getComponent();
1890                if (cn != null && cn.getPackageName().equals(packageName)) {
1891                    try {
1892                        // Add the task to the list to remove if the component no longer exists
1893                        tmpI.setComponent(cn);
1894                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1895                            tasksToRemove.add(p.second);
1896                        }
1897                    } catch (Exception e) {}
1898                }
1899            }
1900            // Prune all the tasks with removed components from the list of recent tasks
1901            synchronized (ActivityManagerService.this) {
1902                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1903                    // Remove the task but don't kill the process (since other components in that
1904                    // package may still be running and in the background)
1905                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1906                }
1907            }
1908        }
1909
1910        @Override
1911        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1912            // Force stop the specified packages
1913            if (packages != null) {
1914                for (String pkg : packages) {
1915                    synchronized (ActivityManagerService.this) {
1916                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1917                                "finished booting")) {
1918                            return true;
1919                        }
1920                    }
1921                }
1922            }
1923            return false;
1924        }
1925    };
1926
1927    public void setSystemProcess() {
1928        try {
1929            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1930            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1931            ServiceManager.addService("meminfo", new MemBinder(this));
1932            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1933            ServiceManager.addService("dbinfo", new DbBinder(this));
1934            if (MONITOR_CPU_USAGE) {
1935                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1936            }
1937            ServiceManager.addService("permission", new PermissionController(this));
1938
1939            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1940                    "android", STOCK_PM_FLAGS);
1941            mSystemThread.installSystemApplicationInfo(info);
1942
1943            synchronized (this) {
1944                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1945                app.persistent = true;
1946                app.pid = MY_PID;
1947                app.maxAdj = ProcessList.SYSTEM_ADJ;
1948                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1949                mProcessNames.put(app.processName, app.uid, app);
1950                synchronized (mPidsSelfLocked) {
1951                    mPidsSelfLocked.put(app.pid, app);
1952                }
1953                updateLruProcessLocked(app, false, null);
1954                updateOomAdjLocked();
1955            }
1956        } catch (PackageManager.NameNotFoundException e) {
1957            throw new RuntimeException(
1958                    "Unable to find android system package", e);
1959        }
1960    }
1961
1962    public void setWindowManager(WindowManagerService wm) {
1963        mWindowManager = wm;
1964        mStackSupervisor.setWindowManager(wm);
1965    }
1966
1967    public void startObservingNativeCrashes() {
1968        final NativeCrashListener ncl = new NativeCrashListener(this);
1969        ncl.start();
1970    }
1971
1972    public IAppOpsService getAppOpsService() {
1973        return mAppOpsService;
1974    }
1975
1976    static class MemBinder extends Binder {
1977        ActivityManagerService mActivityManagerService;
1978        MemBinder(ActivityManagerService activityManagerService) {
1979            mActivityManagerService = activityManagerService;
1980        }
1981
1982        @Override
1983        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1984            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1985                    != PackageManager.PERMISSION_GRANTED) {
1986                pw.println("Permission Denial: can't dump meminfo from from pid="
1987                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1988                        + " without permission " + android.Manifest.permission.DUMP);
1989                return;
1990            }
1991
1992            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1993        }
1994    }
1995
1996    static class GraphicsBinder extends Binder {
1997        ActivityManagerService mActivityManagerService;
1998        GraphicsBinder(ActivityManagerService activityManagerService) {
1999            mActivityManagerService = activityManagerService;
2000        }
2001
2002        @Override
2003        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2004            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2005                    != PackageManager.PERMISSION_GRANTED) {
2006                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2007                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2008                        + " without permission " + android.Manifest.permission.DUMP);
2009                return;
2010            }
2011
2012            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2013        }
2014    }
2015
2016    static class DbBinder extends Binder {
2017        ActivityManagerService mActivityManagerService;
2018        DbBinder(ActivityManagerService activityManagerService) {
2019            mActivityManagerService = activityManagerService;
2020        }
2021
2022        @Override
2023        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2024            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2025                    != PackageManager.PERMISSION_GRANTED) {
2026                pw.println("Permission Denial: can't dump dbinfo from from pid="
2027                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2028                        + " without permission " + android.Manifest.permission.DUMP);
2029                return;
2030            }
2031
2032            mActivityManagerService.dumpDbInfo(fd, pw, args);
2033        }
2034    }
2035
2036    static class CpuBinder extends Binder {
2037        ActivityManagerService mActivityManagerService;
2038        CpuBinder(ActivityManagerService activityManagerService) {
2039            mActivityManagerService = activityManagerService;
2040        }
2041
2042        @Override
2043        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2044            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2045                    != PackageManager.PERMISSION_GRANTED) {
2046                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2047                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2048                        + " without permission " + android.Manifest.permission.DUMP);
2049                return;
2050            }
2051
2052            synchronized (mActivityManagerService.mProcessCpuThread) {
2053                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2054                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2055                        SystemClock.uptimeMillis()));
2056            }
2057        }
2058    }
2059
2060    public static final class Lifecycle extends SystemService {
2061        private final ActivityManagerService mService;
2062
2063        public Lifecycle(Context context) {
2064            super(context);
2065            mService = new ActivityManagerService(context);
2066        }
2067
2068        @Override
2069        public void onStart() {
2070            mService.start();
2071        }
2072
2073        public ActivityManagerService getService() {
2074            return mService;
2075        }
2076    }
2077
2078    // Note: This method is invoked on the main thread but may need to attach various
2079    // handlers to other threads.  So take care to be explicit about the looper.
2080    public ActivityManagerService(Context systemContext) {
2081        mContext = systemContext;
2082        mFactoryTest = FactoryTest.getMode();
2083        mSystemThread = ActivityThread.currentActivityThread();
2084
2085        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2086
2087        mHandlerThread = new ServiceThread(TAG,
2088                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2089        mHandlerThread.start();
2090        mHandler = new MainHandler(mHandlerThread.getLooper());
2091
2092        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2093                "foreground", BROADCAST_FG_TIMEOUT, false);
2094        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2095                "background", BROADCAST_BG_TIMEOUT, true);
2096        mBroadcastQueues[0] = mFgBroadcastQueue;
2097        mBroadcastQueues[1] = mBgBroadcastQueue;
2098
2099        mServices = new ActiveServices(this);
2100        mProviderMap = new ProviderMap(this);
2101
2102        // TODO: Move creation of battery stats service outside of activity manager service.
2103        File dataDir = Environment.getDataDirectory();
2104        File systemDir = new File(dataDir, "system");
2105        systemDir.mkdirs();
2106        mBatteryStatsService = new BatteryStatsService(new File(
2107                systemDir, "batterystats.bin").toString(), mHandler);
2108        mBatteryStatsService.getActiveStatistics().readLocked();
2109        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2110        mOnBattery = DEBUG_POWER ? true
2111                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2112        mBatteryStatsService.getActiveStatistics().setCallback(this);
2113
2114        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2115
2116        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2117        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2118
2119        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2120
2121        // User 0 is the first and only user that runs at boot.
2122        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2123        mUserLru.add(Integer.valueOf(0));
2124        updateStartedUserArrayLocked();
2125
2126        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2127            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2128
2129        mConfiguration.setToDefaults();
2130        mConfiguration.setLocale(Locale.getDefault());
2131
2132        mConfigurationSeq = mConfiguration.seq = 1;
2133        mProcessCpuTracker.init();
2134
2135        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2136        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2137        mStackSupervisor = new ActivityStackSupervisor(this);
2138
2139        mProcessCpuThread = new Thread("CpuTracker") {
2140            @Override
2141            public void run() {
2142                while (true) {
2143                    try {
2144                        try {
2145                            synchronized(this) {
2146                                final long now = SystemClock.uptimeMillis();
2147                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2148                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2149                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2150                                //        + ", write delay=" + nextWriteDelay);
2151                                if (nextWriteDelay < nextCpuDelay) {
2152                                    nextCpuDelay = nextWriteDelay;
2153                                }
2154                                if (nextCpuDelay > 0) {
2155                                    mProcessCpuMutexFree.set(true);
2156                                    this.wait(nextCpuDelay);
2157                                }
2158                            }
2159                        } catch (InterruptedException e) {
2160                        }
2161                        updateCpuStatsNow();
2162                    } catch (Exception e) {
2163                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2164                    }
2165                }
2166            }
2167        };
2168
2169        Watchdog.getInstance().addMonitor(this);
2170        Watchdog.getInstance().addThread(mHandler);
2171    }
2172
2173    public void setSystemServiceManager(SystemServiceManager mgr) {
2174        mSystemServiceManager = mgr;
2175    }
2176
2177    private void start() {
2178        mProcessCpuThread.start();
2179
2180        mBatteryStatsService.publish(mContext);
2181        mUsageStatsService.publish(mContext);
2182        mAppOpsService.publish(mContext);
2183
2184        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2185    }
2186
2187    @Override
2188    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2189            throws RemoteException {
2190        if (code == SYSPROPS_TRANSACTION) {
2191            // We need to tell all apps about the system property change.
2192            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2193            synchronized(this) {
2194                final int NP = mProcessNames.getMap().size();
2195                for (int ip=0; ip<NP; ip++) {
2196                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2197                    final int NA = apps.size();
2198                    for (int ia=0; ia<NA; ia++) {
2199                        ProcessRecord app = apps.valueAt(ia);
2200                        if (app.thread != null) {
2201                            procs.add(app.thread.asBinder());
2202                        }
2203                    }
2204                }
2205            }
2206
2207            int N = procs.size();
2208            for (int i=0; i<N; i++) {
2209                Parcel data2 = Parcel.obtain();
2210                try {
2211                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2212                } catch (RemoteException e) {
2213                }
2214                data2.recycle();
2215            }
2216        }
2217        try {
2218            return super.onTransact(code, data, reply, flags);
2219        } catch (RuntimeException e) {
2220            // The activity manager only throws security exceptions, so let's
2221            // log all others.
2222            if (!(e instanceof SecurityException)) {
2223                Slog.wtf(TAG, "Activity Manager Crash", e);
2224            }
2225            throw e;
2226        }
2227    }
2228
2229    void updateCpuStats() {
2230        final long now = SystemClock.uptimeMillis();
2231        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2232            return;
2233        }
2234        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2235            synchronized (mProcessCpuThread) {
2236                mProcessCpuThread.notify();
2237            }
2238        }
2239    }
2240
2241    void updateCpuStatsNow() {
2242        synchronized (mProcessCpuThread) {
2243            mProcessCpuMutexFree.set(false);
2244            final long now = SystemClock.uptimeMillis();
2245            boolean haveNewCpuStats = false;
2246
2247            if (MONITOR_CPU_USAGE &&
2248                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2249                mLastCpuTime.set(now);
2250                haveNewCpuStats = true;
2251                mProcessCpuTracker.update();
2252                //Slog.i(TAG, mProcessCpu.printCurrentState());
2253                //Slog.i(TAG, "Total CPU usage: "
2254                //        + mProcessCpu.getTotalCpuPercent() + "%");
2255
2256                // Slog the cpu usage if the property is set.
2257                if ("true".equals(SystemProperties.get("events.cpu"))) {
2258                    int user = mProcessCpuTracker.getLastUserTime();
2259                    int system = mProcessCpuTracker.getLastSystemTime();
2260                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2261                    int irq = mProcessCpuTracker.getLastIrqTime();
2262                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2263                    int idle = mProcessCpuTracker.getLastIdleTime();
2264
2265                    int total = user + system + iowait + irq + softIrq + idle;
2266                    if (total == 0) total = 1;
2267
2268                    EventLog.writeEvent(EventLogTags.CPU,
2269                            ((user+system+iowait+irq+softIrq) * 100) / total,
2270                            (user * 100) / total,
2271                            (system * 100) / total,
2272                            (iowait * 100) / total,
2273                            (irq * 100) / total,
2274                            (softIrq * 100) / total);
2275                }
2276            }
2277
2278            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2279            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2280            synchronized(bstats) {
2281                synchronized(mPidsSelfLocked) {
2282                    if (haveNewCpuStats) {
2283                        if (mOnBattery) {
2284                            int perc = bstats.startAddingCpuLocked();
2285                            int totalUTime = 0;
2286                            int totalSTime = 0;
2287                            final int N = mProcessCpuTracker.countStats();
2288                            for (int i=0; i<N; i++) {
2289                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2290                                if (!st.working) {
2291                                    continue;
2292                                }
2293                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2294                                int otherUTime = (st.rel_utime*perc)/100;
2295                                int otherSTime = (st.rel_stime*perc)/100;
2296                                totalUTime += otherUTime;
2297                                totalSTime += otherSTime;
2298                                if (pr != null) {
2299                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2300                                    if (ps == null || !ps.isActive()) {
2301                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2302                                                pr.info.uid, pr.processName);
2303                                    }
2304                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2305                                            st.rel_stime-otherSTime);
2306                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2307                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2308                                } else {
2309                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2310                                    if (ps == null || !ps.isActive()) {
2311                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2312                                                bstats.mapUid(st.uid), st.name);
2313                                    }
2314                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2315                                            st.rel_stime-otherSTime);
2316                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2317                                }
2318                            }
2319                            bstats.finishAddingCpuLocked(perc, totalUTime,
2320                                    totalSTime, cpuSpeedTimes);
2321                        }
2322                    }
2323                }
2324
2325                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2326                    mLastWriteTime = now;
2327                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2328                }
2329            }
2330        }
2331    }
2332
2333    @Override
2334    public void batteryNeedsCpuUpdate() {
2335        updateCpuStatsNow();
2336    }
2337
2338    @Override
2339    public void batteryPowerChanged(boolean onBattery) {
2340        // When plugging in, update the CPU stats first before changing
2341        // the plug state.
2342        updateCpuStatsNow();
2343        synchronized (this) {
2344            synchronized(mPidsSelfLocked) {
2345                mOnBattery = DEBUG_POWER ? true : onBattery;
2346            }
2347        }
2348    }
2349
2350    /**
2351     * Initialize the application bind args. These are passed to each
2352     * process when the bindApplication() IPC is sent to the process. They're
2353     * lazily setup to make sure the services are running when they're asked for.
2354     */
2355    private HashMap<String, IBinder> getCommonServicesLocked() {
2356        if (mAppBindArgs == null) {
2357            mAppBindArgs = new HashMap<String, IBinder>();
2358
2359            // Setup the application init args
2360            mAppBindArgs.put("package", ServiceManager.getService("package"));
2361            mAppBindArgs.put("window", ServiceManager.getService("window"));
2362            mAppBindArgs.put(Context.ALARM_SERVICE,
2363                    ServiceManager.getService(Context.ALARM_SERVICE));
2364        }
2365        return mAppBindArgs;
2366    }
2367
2368    final void setFocusedActivityLocked(ActivityRecord r) {
2369        if (mFocusedActivity != r) {
2370            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2371            mFocusedActivity = r;
2372            if (r.task != null && r.task.voiceInteractor != null) {
2373                startRunningVoiceLocked();
2374            } else {
2375                finishRunningVoiceLocked();
2376            }
2377            mStackSupervisor.setFocusedStack(r);
2378            if (r != null) {
2379                mWindowManager.setFocusedApp(r.appToken, true);
2380            }
2381            applyUpdateLockStateLocked(r);
2382        }
2383    }
2384
2385    final void clearFocusedActivity(ActivityRecord r) {
2386        if (mFocusedActivity == r) {
2387            mFocusedActivity = null;
2388        }
2389    }
2390
2391    @Override
2392    public void setFocusedStack(int stackId) {
2393        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2394        synchronized (ActivityManagerService.this) {
2395            ActivityStack stack = mStackSupervisor.getStack(stackId);
2396            if (stack != null) {
2397                ActivityRecord r = stack.topRunningActivityLocked(null);
2398                if (r != null) {
2399                    setFocusedActivityLocked(r);
2400                }
2401            }
2402        }
2403    }
2404
2405    @Override
2406    public void notifyActivityDrawn(IBinder token) {
2407        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2408        synchronized (this) {
2409            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2410            if (r != null) {
2411                r.task.stack.notifyActivityDrawnLocked(r);
2412            }
2413        }
2414    }
2415
2416    final void applyUpdateLockStateLocked(ActivityRecord r) {
2417        // Modifications to the UpdateLock state are done on our handler, outside
2418        // the activity manager's locks.  The new state is determined based on the
2419        // state *now* of the relevant activity record.  The object is passed to
2420        // the handler solely for logging detail, not to be consulted/modified.
2421        final boolean nextState = r != null && r.immersive;
2422        mHandler.sendMessage(
2423                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2424    }
2425
2426    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2427        Message msg = Message.obtain();
2428        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2429        msg.obj = r.task.askedCompatMode ? null : r;
2430        mHandler.sendMessage(msg);
2431    }
2432
2433    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2434            String what, Object obj, ProcessRecord srcApp) {
2435        app.lastActivityTime = now;
2436
2437        if (app.activities.size() > 0) {
2438            // Don't want to touch dependent processes that are hosting activities.
2439            return index;
2440        }
2441
2442        int lrui = mLruProcesses.lastIndexOf(app);
2443        if (lrui < 0) {
2444            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2445                    + what + " " + obj + " from " + srcApp);
2446            return index;
2447        }
2448
2449        if (lrui >= index) {
2450            // Don't want to cause this to move dependent processes *back* in the
2451            // list as if they were less frequently used.
2452            return index;
2453        }
2454
2455        if (lrui >= mLruProcessActivityStart) {
2456            // Don't want to touch dependent processes that are hosting activities.
2457            return index;
2458        }
2459
2460        mLruProcesses.remove(lrui);
2461        if (index > 0) {
2462            index--;
2463        }
2464        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2465                + " in LRU list: " + app);
2466        mLruProcesses.add(index, app);
2467        return index;
2468    }
2469
2470    final void removeLruProcessLocked(ProcessRecord app) {
2471        int lrui = mLruProcesses.lastIndexOf(app);
2472        if (lrui >= 0) {
2473            if (lrui <= mLruProcessActivityStart) {
2474                mLruProcessActivityStart--;
2475            }
2476            if (lrui <= mLruProcessServiceStart) {
2477                mLruProcessServiceStart--;
2478            }
2479            mLruProcesses.remove(lrui);
2480        }
2481    }
2482
2483    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2484            ProcessRecord client) {
2485        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2486                || app.treatLikeActivity;
2487        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2488        if (!activityChange && hasActivity) {
2489            // The process has activities, so we are only allowing activity-based adjustments
2490            // to move it.  It should be kept in the front of the list with other
2491            // processes that have activities, and we don't want those to change their
2492            // order except due to activity operations.
2493            return;
2494        }
2495
2496        mLruSeq++;
2497        final long now = SystemClock.uptimeMillis();
2498        app.lastActivityTime = now;
2499
2500        // First a quick reject: if the app is already at the position we will
2501        // put it, then there is nothing to do.
2502        if (hasActivity) {
2503            final int N = mLruProcesses.size();
2504            if (N > 0 && mLruProcesses.get(N-1) == app) {
2505                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2506                return;
2507            }
2508        } else {
2509            if (mLruProcessServiceStart > 0
2510                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2511                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2512                return;
2513            }
2514        }
2515
2516        int lrui = mLruProcesses.lastIndexOf(app);
2517
2518        if (app.persistent && lrui >= 0) {
2519            // We don't care about the position of persistent processes, as long as
2520            // they are in the list.
2521            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2522            return;
2523        }
2524
2525        /* In progress: compute new position first, so we can avoid doing work
2526           if the process is not actually going to move.  Not yet working.
2527        int addIndex;
2528        int nextIndex;
2529        boolean inActivity = false, inService = false;
2530        if (hasActivity) {
2531            // Process has activities, put it at the very tipsy-top.
2532            addIndex = mLruProcesses.size();
2533            nextIndex = mLruProcessServiceStart;
2534            inActivity = true;
2535        } else if (hasService) {
2536            // Process has services, put it at the top of the service list.
2537            addIndex = mLruProcessActivityStart;
2538            nextIndex = mLruProcessServiceStart;
2539            inActivity = true;
2540            inService = true;
2541        } else  {
2542            // Process not otherwise of interest, it goes to the top of the non-service area.
2543            addIndex = mLruProcessServiceStart;
2544            if (client != null) {
2545                int clientIndex = mLruProcesses.lastIndexOf(client);
2546                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2547                        + app);
2548                if (clientIndex >= 0 && addIndex > clientIndex) {
2549                    addIndex = clientIndex;
2550                }
2551            }
2552            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2553        }
2554
2555        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2556                + mLruProcessActivityStart + "): " + app);
2557        */
2558
2559        if (lrui >= 0) {
2560            if (lrui < mLruProcessActivityStart) {
2561                mLruProcessActivityStart--;
2562            }
2563            if (lrui < mLruProcessServiceStart) {
2564                mLruProcessServiceStart--;
2565            }
2566            /*
2567            if (addIndex > lrui) {
2568                addIndex--;
2569            }
2570            if (nextIndex > lrui) {
2571                nextIndex--;
2572            }
2573            */
2574            mLruProcesses.remove(lrui);
2575        }
2576
2577        /*
2578        mLruProcesses.add(addIndex, app);
2579        if (inActivity) {
2580            mLruProcessActivityStart++;
2581        }
2582        if (inService) {
2583            mLruProcessActivityStart++;
2584        }
2585        */
2586
2587        int nextIndex;
2588        if (hasActivity) {
2589            final int N = mLruProcesses.size();
2590            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2591                // Process doesn't have activities, but has clients with
2592                // activities...  move it up, but one below the top (the top
2593                // should always have a real activity).
2594                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2595                mLruProcesses.add(N-1, app);
2596                // To keep it from spamming the LRU list (by making a bunch of clients),
2597                // we will push down any other entries owned by the app.
2598                final int uid = app.info.uid;
2599                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2600                    ProcessRecord subProc = mLruProcesses.get(i);
2601                    if (subProc.info.uid == uid) {
2602                        // We want to push this one down the list.  If the process after
2603                        // it is for the same uid, however, don't do so, because we don't
2604                        // want them internally to be re-ordered.
2605                        if (mLruProcesses.get(i-1).info.uid != uid) {
2606                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2607                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2608                            ProcessRecord tmp = mLruProcesses.get(i);
2609                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2610                            mLruProcesses.set(i-1, tmp);
2611                            i--;
2612                        }
2613                    } else {
2614                        // A gap, we can stop here.
2615                        break;
2616                    }
2617                }
2618            } else {
2619                // Process has activities, put it at the very tipsy-top.
2620                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2621                mLruProcesses.add(app);
2622            }
2623            nextIndex = mLruProcessServiceStart;
2624        } else if (hasService) {
2625            // Process has services, put it at the top of the service list.
2626            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2627            mLruProcesses.add(mLruProcessActivityStart, app);
2628            nextIndex = mLruProcessServiceStart;
2629            mLruProcessActivityStart++;
2630        } else  {
2631            // Process not otherwise of interest, it goes to the top of the non-service area.
2632            int index = mLruProcessServiceStart;
2633            if (client != null) {
2634                // If there is a client, don't allow the process to be moved up higher
2635                // in the list than that client.
2636                int clientIndex = mLruProcesses.lastIndexOf(client);
2637                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2638                        + " when updating " + app);
2639                if (clientIndex <= lrui) {
2640                    // Don't allow the client index restriction to push it down farther in the
2641                    // list than it already is.
2642                    clientIndex = lrui;
2643                }
2644                if (clientIndex >= 0 && index > clientIndex) {
2645                    index = clientIndex;
2646                }
2647            }
2648            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2649            mLruProcesses.add(index, app);
2650            nextIndex = index-1;
2651            mLruProcessActivityStart++;
2652            mLruProcessServiceStart++;
2653        }
2654
2655        // If the app is currently using a content provider or service,
2656        // bump those processes as well.
2657        for (int j=app.connections.size()-1; j>=0; j--) {
2658            ConnectionRecord cr = app.connections.valueAt(j);
2659            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2660                    && cr.binding.service.app != null
2661                    && cr.binding.service.app.lruSeq != mLruSeq
2662                    && !cr.binding.service.app.persistent) {
2663                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2664                        "service connection", cr, app);
2665            }
2666        }
2667        for (int j=app.conProviders.size()-1; j>=0; j--) {
2668            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2669            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2670                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2671                        "provider reference", cpr, app);
2672            }
2673        }
2674    }
2675
2676    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2677        if (uid == Process.SYSTEM_UID) {
2678            // The system gets to run in any process.  If there are multiple
2679            // processes with the same uid, just pick the first (this
2680            // should never happen).
2681            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2682            if (procs == null) return null;
2683            final int N = procs.size();
2684            for (int i = 0; i < N; i++) {
2685                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2686            }
2687        }
2688        ProcessRecord proc = mProcessNames.get(processName, uid);
2689        if (false && proc != null && !keepIfLarge
2690                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2691                && proc.lastCachedPss >= 4000) {
2692            // Turn this condition on to cause killing to happen regularly, for testing.
2693            if (proc.baseProcessTracker != null) {
2694                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2695            }
2696            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2697                    + "k from cached");
2698        } else if (proc != null && !keepIfLarge
2699                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2700                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2701            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2702            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2703                if (proc.baseProcessTracker != null) {
2704                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2705                }
2706                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2707                        + "k from cached");
2708            }
2709        }
2710        return proc;
2711    }
2712
2713    void ensurePackageDexOpt(String packageName) {
2714        IPackageManager pm = AppGlobals.getPackageManager();
2715        try {
2716            if (pm.performDexOpt(packageName)) {
2717                mDidDexOpt = true;
2718            }
2719        } catch (RemoteException e) {
2720        }
2721    }
2722
2723    boolean isNextTransitionForward() {
2724        int transit = mWindowManager.getPendingAppTransition();
2725        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2726                || transit == AppTransition.TRANSIT_TASK_OPEN
2727                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2728    }
2729
2730    final ProcessRecord startProcessLocked(String processName,
2731            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2732            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2733            boolean isolated, boolean keepIfLarge) {
2734        ProcessRecord app;
2735        if (!isolated) {
2736            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2737        } else {
2738            // If this is an isolated process, it can't re-use an existing process.
2739            app = null;
2740        }
2741        // We don't have to do anything more if:
2742        // (1) There is an existing application record; and
2743        // (2) The caller doesn't think it is dead, OR there is no thread
2744        //     object attached to it so we know it couldn't have crashed; and
2745        // (3) There is a pid assigned to it, so it is either starting or
2746        //     already running.
2747        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2748                + " app=" + app + " knownToBeDead=" + knownToBeDead
2749                + " thread=" + (app != null ? app.thread : null)
2750                + " pid=" + (app != null ? app.pid : -1));
2751        if (app != null && app.pid > 0) {
2752            if (!knownToBeDead || app.thread == null) {
2753                // We already have the app running, or are waiting for it to
2754                // come up (we have a pid but not yet its thread), so keep it.
2755                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2756                // If this is a new package in the process, add the package to the list
2757                app.addPackage(info.packageName, mProcessStats);
2758                return app;
2759            }
2760
2761            // An application record is attached to a previous process,
2762            // clean it up now.
2763            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2764            handleAppDiedLocked(app, true, true);
2765        }
2766
2767        String hostingNameStr = hostingName != null
2768                ? hostingName.flattenToShortString() : null;
2769
2770        if (!isolated) {
2771            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2772                // If we are in the background, then check to see if this process
2773                // is bad.  If so, we will just silently fail.
2774                if (mBadProcesses.get(info.processName, info.uid) != null) {
2775                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2776                            + "/" + info.processName);
2777                    return null;
2778                }
2779            } else {
2780                // When the user is explicitly starting a process, then clear its
2781                // crash count so that we won't make it bad until they see at
2782                // least one crash dialog again, and make the process good again
2783                // if it had been bad.
2784                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2785                        + "/" + info.processName);
2786                mProcessCrashTimes.remove(info.processName, info.uid);
2787                if (mBadProcesses.get(info.processName, info.uid) != null) {
2788                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2789                            UserHandle.getUserId(info.uid), info.uid,
2790                            info.processName);
2791                    mBadProcesses.remove(info.processName, info.uid);
2792                    if (app != null) {
2793                        app.bad = false;
2794                    }
2795                }
2796            }
2797        }
2798
2799        if (app == null) {
2800            app = newProcessRecordLocked(info, processName, isolated);
2801            if (app == null) {
2802                Slog.w(TAG, "Failed making new process record for "
2803                        + processName + "/" + info.uid + " isolated=" + isolated);
2804                return null;
2805            }
2806            mProcessNames.put(processName, app.uid, app);
2807            if (isolated) {
2808                mIsolatedProcesses.put(app.uid, app);
2809            }
2810        } else {
2811            // If this is a new package in the process, add the package to the list
2812            app.addPackage(info.packageName, mProcessStats);
2813        }
2814
2815        // If the system is not ready yet, then hold off on starting this
2816        // process until it is.
2817        if (!mProcessesReady
2818                && !isAllowedWhileBooting(info)
2819                && !allowWhileBooting) {
2820            if (!mProcessesOnHold.contains(app)) {
2821                mProcessesOnHold.add(app);
2822            }
2823            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2824            return app;
2825        }
2826
2827        startProcessLocked(app, hostingType, hostingNameStr);
2828        return (app.pid != 0) ? app : null;
2829    }
2830
2831    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2832        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2833    }
2834
2835    private final void startProcessLocked(ProcessRecord app,
2836            String hostingType, String hostingNameStr) {
2837        if (app.pid > 0 && app.pid != MY_PID) {
2838            synchronized (mPidsSelfLocked) {
2839                mPidsSelfLocked.remove(app.pid);
2840                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2841            }
2842            app.setPid(0);
2843        }
2844
2845        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2846                "startProcessLocked removing on hold: " + app);
2847        mProcessesOnHold.remove(app);
2848
2849        updateCpuStats();
2850
2851        try {
2852            int uid = app.uid;
2853
2854            int[] gids = null;
2855            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2856            if (!app.isolated) {
2857                int[] permGids = null;
2858                try {
2859                    final PackageManager pm = mContext.getPackageManager();
2860                    permGids = pm.getPackageGids(app.info.packageName);
2861
2862                    if (Environment.isExternalStorageEmulated()) {
2863                        if (pm.checkPermission(
2864                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2865                                app.info.packageName) == PERMISSION_GRANTED) {
2866                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2867                        } else {
2868                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2869                        }
2870                    }
2871                } catch (PackageManager.NameNotFoundException e) {
2872                    Slog.w(TAG, "Unable to retrieve gids", e);
2873                }
2874
2875                /*
2876                 * Add shared application GID so applications can share some
2877                 * resources like shared libraries
2878                 */
2879                if (permGids == null) {
2880                    gids = new int[1];
2881                } else {
2882                    gids = new int[permGids.length + 1];
2883                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2884                }
2885                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2886            }
2887            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2888                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2889                        && mTopComponent != null
2890                        && app.processName.equals(mTopComponent.getPackageName())) {
2891                    uid = 0;
2892                }
2893                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2894                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2895                    uid = 0;
2896                }
2897            }
2898            int debugFlags = 0;
2899            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2900                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2901                // Also turn on CheckJNI for debuggable apps. It's quite
2902                // awkward to turn on otherwise.
2903                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2904            }
2905            // Run the app in safe mode if its manifest requests so or the
2906            // system is booted in safe mode.
2907            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2908                mSafeMode == true) {
2909                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2910            }
2911            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2912                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2913            }
2914            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2915                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2916            }
2917            if ("1".equals(SystemProperties.get("debug.assert"))) {
2918                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2919            }
2920
2921            String requiredAbi = app.info.requiredCpuAbi;
2922            if (requiredAbi == null) {
2923                requiredAbi = Build.SUPPORTED_ABIS[0];
2924            }
2925
2926            // Start the process.  It will either succeed and return a result containing
2927            // the PID of the new process, or else throw a RuntimeException.
2928            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2929                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2930                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2931
2932            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2933            synchronized (bs) {
2934                if (bs.isOnBattery()) {
2935                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2936                }
2937            }
2938
2939            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2940                    UserHandle.getUserId(uid), startResult.pid, uid,
2941                    app.processName, hostingType,
2942                    hostingNameStr != null ? hostingNameStr : "");
2943
2944            if (app.persistent) {
2945                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2946            }
2947
2948            StringBuilder buf = mStringBuilder;
2949            buf.setLength(0);
2950            buf.append("Start proc ");
2951            buf.append(app.processName);
2952            buf.append(" for ");
2953            buf.append(hostingType);
2954            if (hostingNameStr != null) {
2955                buf.append(" ");
2956                buf.append(hostingNameStr);
2957            }
2958            buf.append(": pid=");
2959            buf.append(startResult.pid);
2960            buf.append(" uid=");
2961            buf.append(uid);
2962            buf.append(" gids={");
2963            if (gids != null) {
2964                for (int gi=0; gi<gids.length; gi++) {
2965                    if (gi != 0) buf.append(", ");
2966                    buf.append(gids[gi]);
2967
2968                }
2969            }
2970            buf.append("}");
2971            Slog.i(TAG, buf.toString());
2972            app.setPid(startResult.pid);
2973            app.usingWrapper = startResult.usingWrapper;
2974            app.removed = false;
2975            synchronized (mPidsSelfLocked) {
2976                this.mPidsSelfLocked.put(startResult.pid, app);
2977                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2978                msg.obj = app;
2979                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2980                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2981            }
2982            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2983                    app.processName, app.info.uid);
2984            if (app.isolated) {
2985                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2986            }
2987        } catch (RuntimeException e) {
2988            // XXX do better error recovery.
2989            app.setPid(0);
2990            Slog.e(TAG, "Failure starting process " + app.processName, e);
2991        }
2992    }
2993
2994    void updateUsageStats(ActivityRecord component, boolean resumed) {
2995        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2996        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2997        if (resumed) {
2998            mUsageStatsService.noteResumeComponent(component.realActivity);
2999            synchronized (stats) {
3000                stats.noteActivityResumedLocked(component.app.uid);
3001            }
3002        } else {
3003            mUsageStatsService.notePauseComponent(component.realActivity);
3004            synchronized (stats) {
3005                stats.noteActivityPausedLocked(component.app.uid);
3006            }
3007        }
3008    }
3009
3010    Intent getHomeIntent() {
3011        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3012        intent.setComponent(mTopComponent);
3013        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3014            intent.addCategory(Intent.CATEGORY_HOME);
3015        }
3016        return intent;
3017    }
3018
3019    boolean startHomeActivityLocked(int userId) {
3020        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3021                && mTopAction == null) {
3022            // We are running in factory test mode, but unable to find
3023            // the factory test app, so just sit around displaying the
3024            // error message and don't try to start anything.
3025            return false;
3026        }
3027        Intent intent = getHomeIntent();
3028        ActivityInfo aInfo =
3029            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3030        if (aInfo != null) {
3031            intent.setComponent(new ComponentName(
3032                    aInfo.applicationInfo.packageName, aInfo.name));
3033            // Don't do this if the home app is currently being
3034            // instrumented.
3035            aInfo = new ActivityInfo(aInfo);
3036            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3037            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3038                    aInfo.applicationInfo.uid, true);
3039            if (app == null || app.instrumentationClass == null) {
3040                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3041                mStackSupervisor.startHomeActivity(intent, aInfo);
3042            }
3043        }
3044
3045        return true;
3046    }
3047
3048    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3049        ActivityInfo ai = null;
3050        ComponentName comp = intent.getComponent();
3051        try {
3052            if (comp != null) {
3053                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3054            } else {
3055                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3056                        intent,
3057                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3058                            flags, userId);
3059
3060                if (info != null) {
3061                    ai = info.activityInfo;
3062                }
3063            }
3064        } catch (RemoteException e) {
3065            // ignore
3066        }
3067
3068        return ai;
3069    }
3070
3071    /**
3072     * Starts the "new version setup screen" if appropriate.
3073     */
3074    void startSetupActivityLocked() {
3075        // Only do this once per boot.
3076        if (mCheckedForSetup) {
3077            return;
3078        }
3079
3080        // We will show this screen if the current one is a different
3081        // version than the last one shown, and we are not running in
3082        // low-level factory test mode.
3083        final ContentResolver resolver = mContext.getContentResolver();
3084        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3085                Settings.Global.getInt(resolver,
3086                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3087            mCheckedForSetup = true;
3088
3089            // See if we should be showing the platform update setup UI.
3090            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3091            List<ResolveInfo> ris = mContext.getPackageManager()
3092                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3093
3094            // We don't allow third party apps to replace this.
3095            ResolveInfo ri = null;
3096            for (int i=0; ris != null && i<ris.size(); i++) {
3097                if ((ris.get(i).activityInfo.applicationInfo.flags
3098                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3099                    ri = ris.get(i);
3100                    break;
3101                }
3102            }
3103
3104            if (ri != null) {
3105                String vers = ri.activityInfo.metaData != null
3106                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3107                        : null;
3108                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3109                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3110                            Intent.METADATA_SETUP_VERSION);
3111                }
3112                String lastVers = Settings.Secure.getString(
3113                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3114                if (vers != null && !vers.equals(lastVers)) {
3115                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3116                    intent.setComponent(new ComponentName(
3117                            ri.activityInfo.packageName, ri.activityInfo.name));
3118                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3119                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3120                }
3121            }
3122        }
3123    }
3124
3125    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3126        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3127    }
3128
3129    void enforceNotIsolatedCaller(String caller) {
3130        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3131            throw new SecurityException("Isolated process not allowed to call " + caller);
3132        }
3133    }
3134
3135    @Override
3136    public int getFrontActivityScreenCompatMode() {
3137        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3138        synchronized (this) {
3139            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3140        }
3141    }
3142
3143    @Override
3144    public void setFrontActivityScreenCompatMode(int mode) {
3145        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3146                "setFrontActivityScreenCompatMode");
3147        synchronized (this) {
3148            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3149        }
3150    }
3151
3152    @Override
3153    public int getPackageScreenCompatMode(String packageName) {
3154        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3155        synchronized (this) {
3156            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3157        }
3158    }
3159
3160    @Override
3161    public void setPackageScreenCompatMode(String packageName, int mode) {
3162        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3163                "setPackageScreenCompatMode");
3164        synchronized (this) {
3165            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3166        }
3167    }
3168
3169    @Override
3170    public boolean getPackageAskScreenCompat(String packageName) {
3171        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3172        synchronized (this) {
3173            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3174        }
3175    }
3176
3177    @Override
3178    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3179        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3180                "setPackageAskScreenCompat");
3181        synchronized (this) {
3182            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3183        }
3184    }
3185
3186    private void dispatchProcessesChanged() {
3187        int N;
3188        synchronized (this) {
3189            N = mPendingProcessChanges.size();
3190            if (mActiveProcessChanges.length < N) {
3191                mActiveProcessChanges = new ProcessChangeItem[N];
3192            }
3193            mPendingProcessChanges.toArray(mActiveProcessChanges);
3194            mAvailProcessChanges.addAll(mPendingProcessChanges);
3195            mPendingProcessChanges.clear();
3196            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3197        }
3198
3199        int i = mProcessObservers.beginBroadcast();
3200        while (i > 0) {
3201            i--;
3202            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3203            if (observer != null) {
3204                try {
3205                    for (int j=0; j<N; j++) {
3206                        ProcessChangeItem item = mActiveProcessChanges[j];
3207                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3208                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3209                                    + item.pid + " uid=" + item.uid + ": "
3210                                    + item.foregroundActivities);
3211                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3212                                    item.foregroundActivities);
3213                        }
3214                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3215                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3216                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3217                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3218                        }
3219                    }
3220                } catch (RemoteException e) {
3221                }
3222            }
3223        }
3224        mProcessObservers.finishBroadcast();
3225    }
3226
3227    private void dispatchProcessDied(int pid, int uid) {
3228        int i = mProcessObservers.beginBroadcast();
3229        while (i > 0) {
3230            i--;
3231            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3232            if (observer != null) {
3233                try {
3234                    observer.onProcessDied(pid, uid);
3235                } catch (RemoteException e) {
3236                }
3237            }
3238        }
3239        mProcessObservers.finishBroadcast();
3240    }
3241
3242    final void doPendingActivityLaunchesLocked(boolean doResume) {
3243        final int N = mPendingActivityLaunches.size();
3244        if (N <= 0) {
3245            return;
3246        }
3247        for (int i=0; i<N; i++) {
3248            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3249            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3250                    doResume && i == (N-1), null);
3251        }
3252        mPendingActivityLaunches.clear();
3253    }
3254
3255    @Override
3256    public final int startActivity(IApplicationThread caller, String callingPackage,
3257            Intent intent, String resolvedType, IBinder resultTo,
3258            String resultWho, int requestCode, int startFlags,
3259            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3260        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3261                resultWho, requestCode,
3262                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3263    }
3264
3265    @Override
3266    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3267            Intent intent, String resolvedType, IBinder resultTo,
3268            String resultWho, int requestCode, int startFlags,
3269            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3270        enforceNotIsolatedCaller("startActivity");
3271        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3272                false, true, "startActivity", null);
3273        // TODO: Switch to user app stacks here.
3274        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3275                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3276                null, null, options, userId, null);
3277    }
3278
3279    @Override
3280    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3281            Intent intent, String resolvedType, IBinder resultTo,
3282            String resultWho, int requestCode, int startFlags, String profileFile,
3283            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3284        enforceNotIsolatedCaller("startActivityAndWait");
3285        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3286                false, true, "startActivityAndWait", null);
3287        WaitResult res = new WaitResult();
3288        // TODO: Switch to user app stacks here.
3289        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3290                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3291                res, null, options, UserHandle.getCallingUserId(), null);
3292        return res;
3293    }
3294
3295    @Override
3296    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3297            Intent intent, String resolvedType, IBinder resultTo,
3298            String resultWho, int requestCode, int startFlags, Configuration config,
3299            Bundle options, int userId) {
3300        enforceNotIsolatedCaller("startActivityWithConfig");
3301        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3302                false, true, "startActivityWithConfig", null);
3303        // TODO: Switch to user app stacks here.
3304        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3305                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3306                null, null, null, config, options, userId, null);
3307        return ret;
3308    }
3309
3310    @Override
3311    public int startActivityIntentSender(IApplicationThread caller,
3312            IntentSender intent, Intent fillInIntent, String resolvedType,
3313            IBinder resultTo, String resultWho, int requestCode,
3314            int flagsMask, int flagsValues, Bundle options) {
3315        enforceNotIsolatedCaller("startActivityIntentSender");
3316        // Refuse possible leaked file descriptors
3317        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3318            throw new IllegalArgumentException("File descriptors passed in Intent");
3319        }
3320
3321        IIntentSender sender = intent.getTarget();
3322        if (!(sender instanceof PendingIntentRecord)) {
3323            throw new IllegalArgumentException("Bad PendingIntent object");
3324        }
3325
3326        PendingIntentRecord pir = (PendingIntentRecord)sender;
3327
3328        synchronized (this) {
3329            // If this is coming from the currently resumed activity, it is
3330            // effectively saying that app switches are allowed at this point.
3331            final ActivityStack stack = getFocusedStack();
3332            if (stack.mResumedActivity != null &&
3333                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3334                mAppSwitchesAllowedTime = 0;
3335            }
3336        }
3337        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3338                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3339        return ret;
3340    }
3341
3342    @Override
3343    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3344            Intent intent, String resolvedType, IVoiceInteractionSession session,
3345            IVoiceInteractor interactor, int startFlags, String profileFile,
3346            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3347        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3348                != PackageManager.PERMISSION_GRANTED) {
3349            String msg = "Permission Denial: startVoiceActivity() from pid="
3350                    + Binder.getCallingPid()
3351                    + ", uid=" + Binder.getCallingUid()
3352                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3353            Slog.w(TAG, msg);
3354            throw new SecurityException(msg);
3355        }
3356        if (session == null || interactor == null) {
3357            throw new NullPointerException("null session or interactor");
3358        }
3359        userId = handleIncomingUser(callingPid, callingUid, userId,
3360                false, true, "startVoiceActivity", null);
3361        // TODO: Switch to user app stacks here.
3362        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3363                resolvedType, session, interactor, null, null, 0, startFlags,
3364                profileFile, profileFd, null, null, options, userId, null);
3365    }
3366
3367    @Override
3368    public boolean startNextMatchingActivity(IBinder callingActivity,
3369            Intent intent, Bundle options) {
3370        // Refuse possible leaked file descriptors
3371        if (intent != null && intent.hasFileDescriptors() == true) {
3372            throw new IllegalArgumentException("File descriptors passed in Intent");
3373        }
3374
3375        synchronized (this) {
3376            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3377            if (r == null) {
3378                ActivityOptions.abort(options);
3379                return false;
3380            }
3381            if (r.app == null || r.app.thread == null) {
3382                // The caller is not running...  d'oh!
3383                ActivityOptions.abort(options);
3384                return false;
3385            }
3386            intent = new Intent(intent);
3387            // The caller is not allowed to change the data.
3388            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3389            // And we are resetting to find the next component...
3390            intent.setComponent(null);
3391
3392            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3393
3394            ActivityInfo aInfo = null;
3395            try {
3396                List<ResolveInfo> resolves =
3397                    AppGlobals.getPackageManager().queryIntentActivities(
3398                            intent, r.resolvedType,
3399                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3400                            UserHandle.getCallingUserId());
3401
3402                // Look for the original activity in the list...
3403                final int N = resolves != null ? resolves.size() : 0;
3404                for (int i=0; i<N; i++) {
3405                    ResolveInfo rInfo = resolves.get(i);
3406                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3407                            && rInfo.activityInfo.name.equals(r.info.name)) {
3408                        // We found the current one...  the next matching is
3409                        // after it.
3410                        i++;
3411                        if (i<N) {
3412                            aInfo = resolves.get(i).activityInfo;
3413                        }
3414                        if (debug) {
3415                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3416                                    + "/" + r.info.name);
3417                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3418                                    + "/" + aInfo.name);
3419                        }
3420                        break;
3421                    }
3422                }
3423            } catch (RemoteException e) {
3424            }
3425
3426            if (aInfo == null) {
3427                // Nobody who is next!
3428                ActivityOptions.abort(options);
3429                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3430                return false;
3431            }
3432
3433            intent.setComponent(new ComponentName(
3434                    aInfo.applicationInfo.packageName, aInfo.name));
3435            intent.setFlags(intent.getFlags()&~(
3436                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3437                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3438                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3439                    Intent.FLAG_ACTIVITY_NEW_TASK));
3440
3441            // Okay now we need to start the new activity, replacing the
3442            // currently running activity.  This is a little tricky because
3443            // we want to start the new one as if the current one is finished,
3444            // but not finish the current one first so that there is no flicker.
3445            // And thus...
3446            final boolean wasFinishing = r.finishing;
3447            r.finishing = true;
3448
3449            // Propagate reply information over to the new activity.
3450            final ActivityRecord resultTo = r.resultTo;
3451            final String resultWho = r.resultWho;
3452            final int requestCode = r.requestCode;
3453            r.resultTo = null;
3454            if (resultTo != null) {
3455                resultTo.removeResultsLocked(r, resultWho, requestCode);
3456            }
3457
3458            final long origId = Binder.clearCallingIdentity();
3459            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3460                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3461                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3462                    options, false, null, null);
3463            Binder.restoreCallingIdentity(origId);
3464
3465            r.finishing = wasFinishing;
3466            if (res != ActivityManager.START_SUCCESS) {
3467                return false;
3468            }
3469            return true;
3470        }
3471    }
3472
3473    final int startActivityInPackage(int uid, String callingPackage,
3474            Intent intent, String resolvedType, IBinder resultTo,
3475            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3476                    IActivityContainer container) {
3477
3478        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3479                false, true, "startActivityInPackage", null);
3480
3481        // TODO: Switch to user app stacks here.
3482        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3483                null, null, resultTo, resultWho, requestCode, startFlags,
3484                null, null, null, null, options, userId, container);
3485        return ret;
3486    }
3487
3488    @Override
3489    public final int startActivities(IApplicationThread caller, String callingPackage,
3490            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3491            int userId) {
3492        enforceNotIsolatedCaller("startActivities");
3493        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3494                false, true, "startActivity", null);
3495        // TODO: Switch to user app stacks here.
3496        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3497                resolvedTypes, resultTo, options, userId);
3498        return ret;
3499    }
3500
3501    final int startActivitiesInPackage(int uid, String callingPackage,
3502            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3503            Bundle options, int userId) {
3504
3505        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3506                false, true, "startActivityInPackage", null);
3507        // TODO: Switch to user app stacks here.
3508        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3509                resultTo, options, userId);
3510        return ret;
3511    }
3512
3513    final void addRecentTaskLocked(TaskRecord task) {
3514        int N = mRecentTasks.size();
3515        // Quick case: check if the top-most recent task is the same.
3516        if (N > 0 && mRecentTasks.get(0) == task) {
3517            return;
3518        }
3519        // Another quick case: never add voice sessions.
3520        if (task.voiceSession != null) {
3521            return;
3522        }
3523        // Remove any existing entries that are the same kind of task.
3524        final Intent intent = task.intent;
3525        final boolean document = intent != null && intent.isDocument();
3526        for (int i=0; i<N; i++) {
3527            TaskRecord tr = mRecentTasks.get(i);
3528            if (task != tr) {
3529                if (task.userId != tr.userId) {
3530                    continue;
3531                }
3532                final Intent trIntent = tr.intent;
3533                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3534                    (intent == null || !intent.filterEquals(trIntent))) {
3535                    continue;
3536                }
3537                if (document || trIntent != null && trIntent.isDocument()) {
3538                    // Document tasks do not match other tasks.
3539                    continue;
3540                }
3541            }
3542
3543            // Either task and tr are the same or, their affinities match or their intents match
3544            // and neither of them is a document.
3545            tr.disposeThumbnail();
3546            mRecentTasks.remove(i);
3547            i--;
3548            N--;
3549            if (task.intent == null) {
3550                // If the new recent task we are adding is not fully
3551                // specified, then replace it with the existing recent task.
3552                task = tr;
3553            }
3554        }
3555        if (N >= MAX_RECENT_TASKS) {
3556            mRecentTasks.remove(N-1).disposeThumbnail();
3557        }
3558        mRecentTasks.add(0, task);
3559    }
3560
3561    @Override
3562    public void reportActivityFullyDrawn(IBinder token) {
3563        synchronized (this) {
3564            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3565            if (r == null) {
3566                return;
3567            }
3568            r.reportFullyDrawnLocked();
3569        }
3570    }
3571
3572    @Override
3573    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3574        synchronized (this) {
3575            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3576            if (r == null) {
3577                return;
3578            }
3579            final long origId = Binder.clearCallingIdentity();
3580            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3581            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3582                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3583            if (config != null) {
3584                r.frozenBeforeDestroy = true;
3585                if (!updateConfigurationLocked(config, r, false, false)) {
3586                    mStackSupervisor.resumeTopActivitiesLocked();
3587                }
3588            }
3589            Binder.restoreCallingIdentity(origId);
3590        }
3591    }
3592
3593    @Override
3594    public int getRequestedOrientation(IBinder token) {
3595        synchronized (this) {
3596            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3597            if (r == null) {
3598                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3599            }
3600            return mWindowManager.getAppOrientation(r.appToken);
3601        }
3602    }
3603
3604    /**
3605     * This is the internal entry point for handling Activity.finish().
3606     *
3607     * @param token The Binder token referencing the Activity we want to finish.
3608     * @param resultCode Result code, if any, from this Activity.
3609     * @param resultData Result data (Intent), if any, from this Activity.
3610     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3611     *            the root Activity in the task.
3612     *
3613     * @return Returns true if the activity successfully finished, or false if it is still running.
3614     */
3615    @Override
3616    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3617            boolean finishTask) {
3618        // Refuse possible leaked file descriptors
3619        if (resultData != null && resultData.hasFileDescriptors() == true) {
3620            throw new IllegalArgumentException("File descriptors passed in Intent");
3621        }
3622
3623        synchronized(this) {
3624            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3625            if (r == null) {
3626                return true;
3627            }
3628            // Keep track of the root activity of the task before we finish it
3629            TaskRecord tr = r.task;
3630            ActivityRecord rootR = tr.getRootActivity();
3631            if (mController != null) {
3632                // Find the first activity that is not finishing.
3633                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3634                if (next != null) {
3635                    // ask watcher if this is allowed
3636                    boolean resumeOK = true;
3637                    try {
3638                        resumeOK = mController.activityResuming(next.packageName);
3639                    } catch (RemoteException e) {
3640                        mController = null;
3641                        Watchdog.getInstance().setActivityController(null);
3642                    }
3643
3644                    if (!resumeOK) {
3645                        return false;
3646                    }
3647                }
3648            }
3649            final long origId = Binder.clearCallingIdentity();
3650            try {
3651                boolean res;
3652                if (finishTask && r == rootR) {
3653                    // If requested, remove the task that is associated to this activity only if it
3654                    // was the root activity in the task.  The result code and data is ignored because
3655                    // we don't support returning them across task boundaries.
3656                    res = removeTaskByIdLocked(tr.taskId, 0);
3657                } else {
3658                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3659                            resultData, "app-request", true);
3660                }
3661                return res;
3662            } finally {
3663                Binder.restoreCallingIdentity(origId);
3664            }
3665        }
3666    }
3667
3668    @Override
3669    public final void finishHeavyWeightApp() {
3670        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3671                != PackageManager.PERMISSION_GRANTED) {
3672            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3673                    + Binder.getCallingPid()
3674                    + ", uid=" + Binder.getCallingUid()
3675                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3676            Slog.w(TAG, msg);
3677            throw new SecurityException(msg);
3678        }
3679
3680        synchronized(this) {
3681            if (mHeavyWeightProcess == null) {
3682                return;
3683            }
3684
3685            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3686                    mHeavyWeightProcess.activities);
3687            for (int i=0; i<activities.size(); i++) {
3688                ActivityRecord r = activities.get(i);
3689                if (!r.finishing) {
3690                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3691                            null, "finish-heavy", true);
3692                }
3693            }
3694
3695            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3696                    mHeavyWeightProcess.userId, 0));
3697            mHeavyWeightProcess = null;
3698        }
3699    }
3700
3701    @Override
3702    public void crashApplication(int uid, int initialPid, String packageName,
3703            String message) {
3704        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3705                != PackageManager.PERMISSION_GRANTED) {
3706            String msg = "Permission Denial: crashApplication() from pid="
3707                    + Binder.getCallingPid()
3708                    + ", uid=" + Binder.getCallingUid()
3709                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3710            Slog.w(TAG, msg);
3711            throw new SecurityException(msg);
3712        }
3713
3714        synchronized(this) {
3715            ProcessRecord proc = null;
3716
3717            // Figure out which process to kill.  We don't trust that initialPid
3718            // still has any relation to current pids, so must scan through the
3719            // list.
3720            synchronized (mPidsSelfLocked) {
3721                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3722                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3723                    if (p.uid != uid) {
3724                        continue;
3725                    }
3726                    if (p.pid == initialPid) {
3727                        proc = p;
3728                        break;
3729                    }
3730                    if (p.pkgList.containsKey(packageName)) {
3731                        proc = p;
3732                    }
3733                }
3734            }
3735
3736            if (proc == null) {
3737                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3738                        + " initialPid=" + initialPid
3739                        + " packageName=" + packageName);
3740                return;
3741            }
3742
3743            if (proc.thread != null) {
3744                if (proc.pid == Process.myPid()) {
3745                    Log.w(TAG, "crashApplication: trying to crash self!");
3746                    return;
3747                }
3748                long ident = Binder.clearCallingIdentity();
3749                try {
3750                    proc.thread.scheduleCrash(message);
3751                } catch (RemoteException e) {
3752                }
3753                Binder.restoreCallingIdentity(ident);
3754            }
3755        }
3756    }
3757
3758    @Override
3759    public final void finishSubActivity(IBinder token, String resultWho,
3760            int requestCode) {
3761        synchronized(this) {
3762            final long origId = Binder.clearCallingIdentity();
3763            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3764            if (r != null) {
3765                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3766            }
3767            Binder.restoreCallingIdentity(origId);
3768        }
3769    }
3770
3771    @Override
3772    public boolean finishActivityAffinity(IBinder token) {
3773        synchronized(this) {
3774            final long origId = Binder.clearCallingIdentity();
3775            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3776            boolean res = false;
3777            if (r != null) {
3778                res = r.task.stack.finishActivityAffinityLocked(r);
3779            }
3780            Binder.restoreCallingIdentity(origId);
3781            return res;
3782        }
3783    }
3784
3785    @Override
3786    public boolean willActivityBeVisible(IBinder token) {
3787        synchronized(this) {
3788            ActivityStack stack = ActivityRecord.getStackLocked(token);
3789            if (stack != null) {
3790                return stack.willActivityBeVisibleLocked(token);
3791            }
3792            return false;
3793        }
3794    }
3795
3796    @Override
3797    public void overridePendingTransition(IBinder token, String packageName,
3798            int enterAnim, int exitAnim) {
3799        synchronized(this) {
3800            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3801            if (self == null) {
3802                return;
3803            }
3804
3805            final long origId = Binder.clearCallingIdentity();
3806
3807            if (self.state == ActivityState.RESUMED
3808                    || self.state == ActivityState.PAUSING) {
3809                mWindowManager.overridePendingAppTransition(packageName,
3810                        enterAnim, exitAnim, null);
3811            }
3812
3813            Binder.restoreCallingIdentity(origId);
3814        }
3815    }
3816
3817    /**
3818     * Main function for removing an existing process from the activity manager
3819     * as a result of that process going away.  Clears out all connections
3820     * to the process.
3821     */
3822    private final void handleAppDiedLocked(ProcessRecord app,
3823            boolean restarting, boolean allowRestart) {
3824        int pid = app.pid;
3825        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3826        if (!restarting) {
3827            removeLruProcessLocked(app);
3828            if (pid > 0) {
3829                ProcessList.remove(pid);
3830            }
3831        }
3832
3833        if (mProfileProc == app) {
3834            clearProfilerLocked();
3835        }
3836
3837        // Remove this application's activities from active lists.
3838        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3839
3840        app.activities.clear();
3841
3842        if (app.instrumentationClass != null) {
3843            Slog.w(TAG, "Crash of app " + app.processName
3844                  + " running instrumentation " + app.instrumentationClass);
3845            Bundle info = new Bundle();
3846            info.putString("shortMsg", "Process crashed.");
3847            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3848        }
3849
3850        if (!restarting) {
3851            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3852                // If there was nothing to resume, and we are not already
3853                // restarting this process, but there is a visible activity that
3854                // is hosted by the process...  then make sure all visible
3855                // activities are running, taking care of restarting this
3856                // process.
3857                if (hasVisibleActivities) {
3858                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3859                }
3860            }
3861        }
3862    }
3863
3864    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3865        IBinder threadBinder = thread.asBinder();
3866        // Find the application record.
3867        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3868            ProcessRecord rec = mLruProcesses.get(i);
3869            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3870                return i;
3871            }
3872        }
3873        return -1;
3874    }
3875
3876    final ProcessRecord getRecordForAppLocked(
3877            IApplicationThread thread) {
3878        if (thread == null) {
3879            return null;
3880        }
3881
3882        int appIndex = getLRURecordIndexForAppLocked(thread);
3883        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3884    }
3885
3886    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3887        // If there are no longer any background processes running,
3888        // and the app that died was not running instrumentation,
3889        // then tell everyone we are now low on memory.
3890        boolean haveBg = false;
3891        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3892            ProcessRecord rec = mLruProcesses.get(i);
3893            if (rec.thread != null
3894                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3895                haveBg = true;
3896                break;
3897            }
3898        }
3899
3900        if (!haveBg) {
3901            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3902            if (doReport) {
3903                long now = SystemClock.uptimeMillis();
3904                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3905                    doReport = false;
3906                } else {
3907                    mLastMemUsageReportTime = now;
3908                }
3909            }
3910            final ArrayList<ProcessMemInfo> memInfos
3911                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3912            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3913            long now = SystemClock.uptimeMillis();
3914            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3915                ProcessRecord rec = mLruProcesses.get(i);
3916                if (rec == dyingProc || rec.thread == null) {
3917                    continue;
3918                }
3919                if (doReport) {
3920                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3921                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3922                }
3923                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3924                    // The low memory report is overriding any current
3925                    // state for a GC request.  Make sure to do
3926                    // heavy/important/visible/foreground processes first.
3927                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3928                        rec.lastRequestedGc = 0;
3929                    } else {
3930                        rec.lastRequestedGc = rec.lastLowMemory;
3931                    }
3932                    rec.reportLowMemory = true;
3933                    rec.lastLowMemory = now;
3934                    mProcessesToGc.remove(rec);
3935                    addProcessToGcListLocked(rec);
3936                }
3937            }
3938            if (doReport) {
3939                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3940                mHandler.sendMessage(msg);
3941            }
3942            scheduleAppGcsLocked();
3943        }
3944    }
3945
3946    final void appDiedLocked(ProcessRecord app, int pid,
3947            IApplicationThread thread) {
3948
3949        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3950        synchronized (stats) {
3951            stats.noteProcessDiedLocked(app.info.uid, pid);
3952        }
3953
3954        // Clean up already done if the process has been re-started.
3955        if (app.pid == pid && app.thread != null &&
3956                app.thread.asBinder() == thread.asBinder()) {
3957            boolean doLowMem = app.instrumentationClass == null;
3958            boolean doOomAdj = doLowMem;
3959            if (!app.killedByAm) {
3960                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3961                        + ") has died.");
3962                mAllowLowerMemLevel = true;
3963            } else {
3964                // Note that we always want to do oom adj to update our state with the
3965                // new number of procs.
3966                mAllowLowerMemLevel = false;
3967                doLowMem = false;
3968            }
3969            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3970            if (DEBUG_CLEANUP) Slog.v(
3971                TAG, "Dying app: " + app + ", pid: " + pid
3972                + ", thread: " + thread.asBinder());
3973            handleAppDiedLocked(app, false, true);
3974
3975            if (doOomAdj) {
3976                updateOomAdjLocked();
3977            }
3978            if (doLowMem) {
3979                doLowMemReportIfNeededLocked(app);
3980            }
3981        } else if (app.pid != pid) {
3982            // A new process has already been started.
3983            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3984                    + ") has died and restarted (pid " + app.pid + ").");
3985            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3986        } else if (DEBUG_PROCESSES) {
3987            Slog.d(TAG, "Received spurious death notification for thread "
3988                    + thread.asBinder());
3989        }
3990    }
3991
3992    /**
3993     * If a stack trace dump file is configured, dump process stack traces.
3994     * @param clearTraces causes the dump file to be erased prior to the new
3995     *    traces being written, if true; when false, the new traces will be
3996     *    appended to any existing file content.
3997     * @param firstPids of dalvik VM processes to dump stack traces for first
3998     * @param lastPids of dalvik VM processes to dump stack traces for last
3999     * @param nativeProcs optional list of native process names to dump stack crawls
4000     * @return file containing stack traces, or null if no dump file is configured
4001     */
4002    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4003            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4004        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4005        if (tracesPath == null || tracesPath.length() == 0) {
4006            return null;
4007        }
4008
4009        File tracesFile = new File(tracesPath);
4010        try {
4011            File tracesDir = tracesFile.getParentFile();
4012            if (!tracesDir.exists()) {
4013                tracesFile.mkdirs();
4014                if (!SELinux.restorecon(tracesDir)) {
4015                    return null;
4016                }
4017            }
4018            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4019
4020            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4021            tracesFile.createNewFile();
4022            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4023        } catch (IOException e) {
4024            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4025            return null;
4026        }
4027
4028        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4029        return tracesFile;
4030    }
4031
4032    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4033            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4034        // Use a FileObserver to detect when traces finish writing.
4035        // The order of traces is considered important to maintain for legibility.
4036        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4037            @Override
4038            public synchronized void onEvent(int event, String path) { notify(); }
4039        };
4040
4041        try {
4042            observer.startWatching();
4043
4044            // First collect all of the stacks of the most important pids.
4045            if (firstPids != null) {
4046                try {
4047                    int num = firstPids.size();
4048                    for (int i = 0; i < num; i++) {
4049                        synchronized (observer) {
4050                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4051                            observer.wait(200);  // Wait for write-close, give up after 200msec
4052                        }
4053                    }
4054                } catch (InterruptedException e) {
4055                    Log.wtf(TAG, e);
4056                }
4057            }
4058
4059            // Next collect the stacks of the native pids
4060            if (nativeProcs != null) {
4061                int[] pids = Process.getPidsForCommands(nativeProcs);
4062                if (pids != null) {
4063                    for (int pid : pids) {
4064                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4065                    }
4066                }
4067            }
4068
4069            // Lastly, measure CPU usage.
4070            if (processCpuTracker != null) {
4071                processCpuTracker.init();
4072                System.gc();
4073                processCpuTracker.update();
4074                try {
4075                    synchronized (processCpuTracker) {
4076                        processCpuTracker.wait(500); // measure over 1/2 second.
4077                    }
4078                } catch (InterruptedException e) {
4079                }
4080                processCpuTracker.update();
4081
4082                // We'll take the stack crawls of just the top apps using CPU.
4083                final int N = processCpuTracker.countWorkingStats();
4084                int numProcs = 0;
4085                for (int i=0; i<N && numProcs<5; i++) {
4086                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4087                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4088                        numProcs++;
4089                        try {
4090                            synchronized (observer) {
4091                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4092                                observer.wait(200);  // Wait for write-close, give up after 200msec
4093                            }
4094                        } catch (InterruptedException e) {
4095                            Log.wtf(TAG, e);
4096                        }
4097
4098                    }
4099                }
4100            }
4101        } finally {
4102            observer.stopWatching();
4103        }
4104    }
4105
4106    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4107        if (true || IS_USER_BUILD) {
4108            return;
4109        }
4110        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4111        if (tracesPath == null || tracesPath.length() == 0) {
4112            return;
4113        }
4114
4115        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4116        StrictMode.allowThreadDiskWrites();
4117        try {
4118            final File tracesFile = new File(tracesPath);
4119            final File tracesDir = tracesFile.getParentFile();
4120            final File tracesTmp = new File(tracesDir, "__tmp__");
4121            try {
4122                if (!tracesDir.exists()) {
4123                    tracesFile.mkdirs();
4124                    if (!SELinux.restorecon(tracesDir.getPath())) {
4125                        return;
4126                    }
4127                }
4128                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4129
4130                if (tracesFile.exists()) {
4131                    tracesTmp.delete();
4132                    tracesFile.renameTo(tracesTmp);
4133                }
4134                StringBuilder sb = new StringBuilder();
4135                Time tobj = new Time();
4136                tobj.set(System.currentTimeMillis());
4137                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4138                sb.append(": ");
4139                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4140                sb.append(" since ");
4141                sb.append(msg);
4142                FileOutputStream fos = new FileOutputStream(tracesFile);
4143                fos.write(sb.toString().getBytes());
4144                if (app == null) {
4145                    fos.write("\n*** No application process!".getBytes());
4146                }
4147                fos.close();
4148                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4149            } catch (IOException e) {
4150                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4151                return;
4152            }
4153
4154            if (app != null) {
4155                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4156                firstPids.add(app.pid);
4157                dumpStackTraces(tracesPath, firstPids, null, null, null);
4158            }
4159
4160            File lastTracesFile = null;
4161            File curTracesFile = null;
4162            for (int i=9; i>=0; i--) {
4163                String name = String.format(Locale.US, "slow%02d.txt", i);
4164                curTracesFile = new File(tracesDir, name);
4165                if (curTracesFile.exists()) {
4166                    if (lastTracesFile != null) {
4167                        curTracesFile.renameTo(lastTracesFile);
4168                    } else {
4169                        curTracesFile.delete();
4170                    }
4171                }
4172                lastTracesFile = curTracesFile;
4173            }
4174            tracesFile.renameTo(curTracesFile);
4175            if (tracesTmp.exists()) {
4176                tracesTmp.renameTo(tracesFile);
4177            }
4178        } finally {
4179            StrictMode.setThreadPolicy(oldPolicy);
4180        }
4181    }
4182
4183    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4184            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4185        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4186        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4187
4188        if (mController != null) {
4189            try {
4190                // 0 == continue, -1 = kill process immediately
4191                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4192                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4193            } catch (RemoteException e) {
4194                mController = null;
4195                Watchdog.getInstance().setActivityController(null);
4196            }
4197        }
4198
4199        long anrTime = SystemClock.uptimeMillis();
4200        if (MONITOR_CPU_USAGE) {
4201            updateCpuStatsNow();
4202        }
4203
4204        synchronized (this) {
4205            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4206            if (mShuttingDown) {
4207                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4208                return;
4209            } else if (app.notResponding) {
4210                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4211                return;
4212            } else if (app.crashing) {
4213                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4214                return;
4215            }
4216
4217            // In case we come through here for the same app before completing
4218            // this one, mark as anring now so we will bail out.
4219            app.notResponding = true;
4220
4221            // Log the ANR to the event log.
4222            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4223                    app.processName, app.info.flags, annotation);
4224
4225            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4226            firstPids.add(app.pid);
4227
4228            int parentPid = app.pid;
4229            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4230            if (parentPid != app.pid) firstPids.add(parentPid);
4231
4232            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4233
4234            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4235                ProcessRecord r = mLruProcesses.get(i);
4236                if (r != null && r.thread != null) {
4237                    int pid = r.pid;
4238                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4239                        if (r.persistent) {
4240                            firstPids.add(pid);
4241                        } else {
4242                            lastPids.put(pid, Boolean.TRUE);
4243                        }
4244                    }
4245                }
4246            }
4247        }
4248
4249        // Log the ANR to the main log.
4250        StringBuilder info = new StringBuilder();
4251        info.setLength(0);
4252        info.append("ANR in ").append(app.processName);
4253        if (activity != null && activity.shortComponentName != null) {
4254            info.append(" (").append(activity.shortComponentName).append(")");
4255        }
4256        info.append("\n");
4257        info.append("PID: ").append(app.pid).append("\n");
4258        if (annotation != null) {
4259            info.append("Reason: ").append(annotation).append("\n");
4260        }
4261        if (parent != null && parent != activity) {
4262            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4263        }
4264
4265        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4266
4267        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4268                NATIVE_STACKS_OF_INTEREST);
4269
4270        String cpuInfo = null;
4271        if (MONITOR_CPU_USAGE) {
4272            updateCpuStatsNow();
4273            synchronized (mProcessCpuThread) {
4274                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4275            }
4276            info.append(processCpuTracker.printCurrentLoad());
4277            info.append(cpuInfo);
4278        }
4279
4280        info.append(processCpuTracker.printCurrentState(anrTime));
4281
4282        Slog.e(TAG, info.toString());
4283        if (tracesFile == null) {
4284            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4285            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4286        }
4287
4288        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4289                cpuInfo, tracesFile, null);
4290
4291        if (mController != null) {
4292            try {
4293                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4294                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4295                if (res != 0) {
4296                    if (res < 0 && app.pid != MY_PID) {
4297                        Process.killProcess(app.pid);
4298                    } else {
4299                        synchronized (this) {
4300                            mServices.scheduleServiceTimeoutLocked(app);
4301                        }
4302                    }
4303                    return;
4304                }
4305            } catch (RemoteException e) {
4306                mController = null;
4307                Watchdog.getInstance().setActivityController(null);
4308            }
4309        }
4310
4311        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4312        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4313                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4314
4315        synchronized (this) {
4316            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4317                killUnneededProcessLocked(app, "background ANR");
4318                return;
4319            }
4320
4321            // Set the app's notResponding state, and look up the errorReportReceiver
4322            makeAppNotRespondingLocked(app,
4323                    activity != null ? activity.shortComponentName : null,
4324                    annotation != null ? "ANR " + annotation : "ANR",
4325                    info.toString());
4326
4327            // Bring up the infamous App Not Responding dialog
4328            Message msg = Message.obtain();
4329            HashMap<String, Object> map = new HashMap<String, Object>();
4330            msg.what = SHOW_NOT_RESPONDING_MSG;
4331            msg.obj = map;
4332            msg.arg1 = aboveSystem ? 1 : 0;
4333            map.put("app", app);
4334            if (activity != null) {
4335                map.put("activity", activity);
4336            }
4337
4338            mHandler.sendMessage(msg);
4339        }
4340    }
4341
4342    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4343        if (!mLaunchWarningShown) {
4344            mLaunchWarningShown = true;
4345            mHandler.post(new Runnable() {
4346                @Override
4347                public void run() {
4348                    synchronized (ActivityManagerService.this) {
4349                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4350                        d.show();
4351                        mHandler.postDelayed(new Runnable() {
4352                            @Override
4353                            public void run() {
4354                                synchronized (ActivityManagerService.this) {
4355                                    d.dismiss();
4356                                    mLaunchWarningShown = false;
4357                                }
4358                            }
4359                        }, 4000);
4360                    }
4361                }
4362            });
4363        }
4364    }
4365
4366    @Override
4367    public boolean clearApplicationUserData(final String packageName,
4368            final IPackageDataObserver observer, int userId) {
4369        enforceNotIsolatedCaller("clearApplicationUserData");
4370        int uid = Binder.getCallingUid();
4371        int pid = Binder.getCallingPid();
4372        userId = handleIncomingUser(pid, uid,
4373                userId, false, true, "clearApplicationUserData", null);
4374        long callingId = Binder.clearCallingIdentity();
4375        try {
4376            IPackageManager pm = AppGlobals.getPackageManager();
4377            int pkgUid = -1;
4378            synchronized(this) {
4379                try {
4380                    pkgUid = pm.getPackageUid(packageName, userId);
4381                } catch (RemoteException e) {
4382                }
4383                if (pkgUid == -1) {
4384                    Slog.w(TAG, "Invalid packageName: " + packageName);
4385                    if (observer != null) {
4386                        try {
4387                            observer.onRemoveCompleted(packageName, false);
4388                        } catch (RemoteException e) {
4389                            Slog.i(TAG, "Observer no longer exists.");
4390                        }
4391                    }
4392                    return false;
4393                }
4394                if (uid == pkgUid || checkComponentPermission(
4395                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4396                        pid, uid, -1, true)
4397                        == PackageManager.PERMISSION_GRANTED) {
4398                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4399                } else {
4400                    throw new SecurityException("PID " + pid + " does not have permission "
4401                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4402                                    + " of package " + packageName);
4403                }
4404            }
4405
4406            try {
4407                // Clear application user data
4408                pm.clearApplicationUserData(packageName, observer, userId);
4409
4410                // Remove all permissions granted from/to this package
4411                removeUriPermissionsForPackageLocked(packageName, userId, true);
4412
4413                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4414                        Uri.fromParts("package", packageName, null));
4415                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4416                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4417                        null, null, 0, null, null, null, false, false, userId);
4418            } catch (RemoteException e) {
4419            }
4420        } finally {
4421            Binder.restoreCallingIdentity(callingId);
4422        }
4423        return true;
4424    }
4425
4426    @Override
4427    public void killBackgroundProcesses(final String packageName, int userId) {
4428        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4429                != PackageManager.PERMISSION_GRANTED &&
4430                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4431                        != PackageManager.PERMISSION_GRANTED) {
4432            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4433                    + Binder.getCallingPid()
4434                    + ", uid=" + Binder.getCallingUid()
4435                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4436            Slog.w(TAG, msg);
4437            throw new SecurityException(msg);
4438        }
4439
4440        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4441                userId, true, true, "killBackgroundProcesses", null);
4442        long callingId = Binder.clearCallingIdentity();
4443        try {
4444            IPackageManager pm = AppGlobals.getPackageManager();
4445            synchronized(this) {
4446                int appId = -1;
4447                try {
4448                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4449                } catch (RemoteException e) {
4450                }
4451                if (appId == -1) {
4452                    Slog.w(TAG, "Invalid packageName: " + packageName);
4453                    return;
4454                }
4455                killPackageProcessesLocked(packageName, appId, userId,
4456                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4457            }
4458        } finally {
4459            Binder.restoreCallingIdentity(callingId);
4460        }
4461    }
4462
4463    @Override
4464    public void killAllBackgroundProcesses() {
4465        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4466                != PackageManager.PERMISSION_GRANTED) {
4467            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4468                    + Binder.getCallingPid()
4469                    + ", uid=" + Binder.getCallingUid()
4470                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4471            Slog.w(TAG, msg);
4472            throw new SecurityException(msg);
4473        }
4474
4475        long callingId = Binder.clearCallingIdentity();
4476        try {
4477            synchronized(this) {
4478                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4479                final int NP = mProcessNames.getMap().size();
4480                for (int ip=0; ip<NP; ip++) {
4481                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4482                    final int NA = apps.size();
4483                    for (int ia=0; ia<NA; ia++) {
4484                        ProcessRecord app = apps.valueAt(ia);
4485                        if (app.persistent) {
4486                            // we don't kill persistent processes
4487                            continue;
4488                        }
4489                        if (app.removed) {
4490                            procs.add(app);
4491                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4492                            app.removed = true;
4493                            procs.add(app);
4494                        }
4495                    }
4496                }
4497
4498                int N = procs.size();
4499                for (int i=0; i<N; i++) {
4500                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4501                }
4502                mAllowLowerMemLevel = true;
4503                updateOomAdjLocked();
4504                doLowMemReportIfNeededLocked(null);
4505            }
4506        } finally {
4507            Binder.restoreCallingIdentity(callingId);
4508        }
4509    }
4510
4511    @Override
4512    public void forceStopPackage(final String packageName, int userId) {
4513        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4514                != PackageManager.PERMISSION_GRANTED) {
4515            String msg = "Permission Denial: forceStopPackage() from pid="
4516                    + Binder.getCallingPid()
4517                    + ", uid=" + Binder.getCallingUid()
4518                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4519            Slog.w(TAG, msg);
4520            throw new SecurityException(msg);
4521        }
4522        final int callingPid = Binder.getCallingPid();
4523        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4524                userId, true, true, "forceStopPackage", null);
4525        long callingId = Binder.clearCallingIdentity();
4526        try {
4527            IPackageManager pm = AppGlobals.getPackageManager();
4528            synchronized(this) {
4529                int[] users = userId == UserHandle.USER_ALL
4530                        ? getUsersLocked() : new int[] { userId };
4531                for (int user : users) {
4532                    int pkgUid = -1;
4533                    try {
4534                        pkgUid = pm.getPackageUid(packageName, user);
4535                    } catch (RemoteException e) {
4536                    }
4537                    if (pkgUid == -1) {
4538                        Slog.w(TAG, "Invalid packageName: " + packageName);
4539                        continue;
4540                    }
4541                    try {
4542                        pm.setPackageStoppedState(packageName, true, user);
4543                    } catch (RemoteException e) {
4544                    } catch (IllegalArgumentException e) {
4545                        Slog.w(TAG, "Failed trying to unstop package "
4546                                + packageName + ": " + e);
4547                    }
4548                    if (isUserRunningLocked(user, false)) {
4549                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4550                    }
4551                }
4552            }
4553        } finally {
4554            Binder.restoreCallingIdentity(callingId);
4555        }
4556    }
4557
4558    /*
4559     * The pkg name and app id have to be specified.
4560     */
4561    @Override
4562    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4563        if (pkg == null) {
4564            return;
4565        }
4566        // Make sure the uid is valid.
4567        if (appid < 0) {
4568            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4569            return;
4570        }
4571        int callerUid = Binder.getCallingUid();
4572        // Only the system server can kill an application
4573        if (callerUid == Process.SYSTEM_UID) {
4574            // Post an aysnc message to kill the application
4575            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4576            msg.arg1 = appid;
4577            msg.arg2 = 0;
4578            Bundle bundle = new Bundle();
4579            bundle.putString("pkg", pkg);
4580            bundle.putString("reason", reason);
4581            msg.obj = bundle;
4582            mHandler.sendMessage(msg);
4583        } else {
4584            throw new SecurityException(callerUid + " cannot kill pkg: " +
4585                    pkg);
4586        }
4587    }
4588
4589    @Override
4590    public void closeSystemDialogs(String reason) {
4591        enforceNotIsolatedCaller("closeSystemDialogs");
4592
4593        final int pid = Binder.getCallingPid();
4594        final int uid = Binder.getCallingUid();
4595        final long origId = Binder.clearCallingIdentity();
4596        try {
4597            synchronized (this) {
4598                // Only allow this from foreground processes, so that background
4599                // applications can't abuse it to prevent system UI from being shown.
4600                if (uid >= Process.FIRST_APPLICATION_UID) {
4601                    ProcessRecord proc;
4602                    synchronized (mPidsSelfLocked) {
4603                        proc = mPidsSelfLocked.get(pid);
4604                    }
4605                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4606                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4607                                + " from background process " + proc);
4608                        return;
4609                    }
4610                }
4611                closeSystemDialogsLocked(reason);
4612            }
4613        } finally {
4614            Binder.restoreCallingIdentity(origId);
4615        }
4616    }
4617
4618    void closeSystemDialogsLocked(String reason) {
4619        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4620        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4621                | Intent.FLAG_RECEIVER_FOREGROUND);
4622        if (reason != null) {
4623            intent.putExtra("reason", reason);
4624        }
4625        mWindowManager.closeSystemDialogs(reason);
4626
4627        mStackSupervisor.closeSystemDialogsLocked();
4628
4629        broadcastIntentLocked(null, null, intent, null,
4630                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4631                Process.SYSTEM_UID, UserHandle.USER_ALL);
4632    }
4633
4634    @Override
4635    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4636        enforceNotIsolatedCaller("getProcessMemoryInfo");
4637        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4638        for (int i=pids.length-1; i>=0; i--) {
4639            ProcessRecord proc;
4640            int oomAdj;
4641            synchronized (this) {
4642                synchronized (mPidsSelfLocked) {
4643                    proc = mPidsSelfLocked.get(pids[i]);
4644                    oomAdj = proc != null ? proc.setAdj : 0;
4645                }
4646            }
4647            infos[i] = new Debug.MemoryInfo();
4648            Debug.getMemoryInfo(pids[i], infos[i]);
4649            if (proc != null) {
4650                synchronized (this) {
4651                    if (proc.thread != null && proc.setAdj == oomAdj) {
4652                        // Record this for posterity if the process has been stable.
4653                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4654                                infos[i].getTotalUss(), false, proc.pkgList);
4655                    }
4656                }
4657            }
4658        }
4659        return infos;
4660    }
4661
4662    @Override
4663    public long[] getProcessPss(int[] pids) {
4664        enforceNotIsolatedCaller("getProcessPss");
4665        long[] pss = new long[pids.length];
4666        for (int i=pids.length-1; i>=0; i--) {
4667            ProcessRecord proc;
4668            int oomAdj;
4669            synchronized (this) {
4670                synchronized (mPidsSelfLocked) {
4671                    proc = mPidsSelfLocked.get(pids[i]);
4672                    oomAdj = proc != null ? proc.setAdj : 0;
4673                }
4674            }
4675            long[] tmpUss = new long[1];
4676            pss[i] = Debug.getPss(pids[i], tmpUss);
4677            if (proc != null) {
4678                synchronized (this) {
4679                    if (proc.thread != null && proc.setAdj == oomAdj) {
4680                        // Record this for posterity if the process has been stable.
4681                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4682                    }
4683                }
4684            }
4685        }
4686        return pss;
4687    }
4688
4689    @Override
4690    public void killApplicationProcess(String processName, int uid) {
4691        if (processName == null) {
4692            return;
4693        }
4694
4695        int callerUid = Binder.getCallingUid();
4696        // Only the system server can kill an application
4697        if (callerUid == Process.SYSTEM_UID) {
4698            synchronized (this) {
4699                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4700                if (app != null && app.thread != null) {
4701                    try {
4702                        app.thread.scheduleSuicide();
4703                    } catch (RemoteException e) {
4704                        // If the other end already died, then our work here is done.
4705                    }
4706                } else {
4707                    Slog.w(TAG, "Process/uid not found attempting kill of "
4708                            + processName + " / " + uid);
4709                }
4710            }
4711        } else {
4712            throw new SecurityException(callerUid + " cannot kill app process: " +
4713                    processName);
4714        }
4715    }
4716
4717    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4718        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4719                false, true, false, false, UserHandle.getUserId(uid), reason);
4720        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4721                Uri.fromParts("package", packageName, null));
4722        if (!mProcessesReady) {
4723            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4724                    | Intent.FLAG_RECEIVER_FOREGROUND);
4725        }
4726        intent.putExtra(Intent.EXTRA_UID, uid);
4727        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4728        broadcastIntentLocked(null, null, intent,
4729                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4730                false, false,
4731                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4732    }
4733
4734    private void forceStopUserLocked(int userId, String reason) {
4735        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4736        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4737        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4738                | Intent.FLAG_RECEIVER_FOREGROUND);
4739        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4740        broadcastIntentLocked(null, null, intent,
4741                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4742                false, false,
4743                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4744    }
4745
4746    private final boolean killPackageProcessesLocked(String packageName, int appId,
4747            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4748            boolean doit, boolean evenPersistent, String reason) {
4749        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4750
4751        // Remove all processes this package may have touched: all with the
4752        // same UID (except for the system or root user), and all whose name
4753        // matches the package name.
4754        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4755        final int NP = mProcessNames.getMap().size();
4756        for (int ip=0; ip<NP; ip++) {
4757            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4758            final int NA = apps.size();
4759            for (int ia=0; ia<NA; ia++) {
4760                ProcessRecord app = apps.valueAt(ia);
4761                if (app.persistent && !evenPersistent) {
4762                    // we don't kill persistent processes
4763                    continue;
4764                }
4765                if (app.removed) {
4766                    if (doit) {
4767                        procs.add(app);
4768                    }
4769                    continue;
4770                }
4771
4772                // Skip process if it doesn't meet our oom adj requirement.
4773                if (app.setAdj < minOomAdj) {
4774                    continue;
4775                }
4776
4777                // If no package is specified, we call all processes under the
4778                // give user id.
4779                if (packageName == null) {
4780                    if (app.userId != userId) {
4781                        continue;
4782                    }
4783                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4784                        continue;
4785                    }
4786                // Package has been specified, we want to hit all processes
4787                // that match it.  We need to qualify this by the processes
4788                // that are running under the specified app and user ID.
4789                } else {
4790                    if (UserHandle.getAppId(app.uid) != appId) {
4791                        continue;
4792                    }
4793                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4794                        continue;
4795                    }
4796                    if (!app.pkgList.containsKey(packageName)) {
4797                        continue;
4798                    }
4799                }
4800
4801                // Process has passed all conditions, kill it!
4802                if (!doit) {
4803                    return true;
4804                }
4805                app.removed = true;
4806                procs.add(app);
4807            }
4808        }
4809
4810        int N = procs.size();
4811        for (int i=0; i<N; i++) {
4812            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4813        }
4814        updateOomAdjLocked();
4815        return N > 0;
4816    }
4817
4818    private final boolean forceStopPackageLocked(String name, int appId,
4819            boolean callerWillRestart, boolean purgeCache, boolean doit,
4820            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4821        int i;
4822        int N;
4823
4824        if (userId == UserHandle.USER_ALL && name == null) {
4825            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4826        }
4827
4828        if (appId < 0 && name != null) {
4829            try {
4830                appId = UserHandle.getAppId(
4831                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4832            } catch (RemoteException e) {
4833            }
4834        }
4835
4836        if (doit) {
4837            if (name != null) {
4838                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4839                        + " user=" + userId + ": " + reason);
4840            } else {
4841                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4842            }
4843
4844            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4845            for (int ip=pmap.size()-1; ip>=0; ip--) {
4846                SparseArray<Long> ba = pmap.valueAt(ip);
4847                for (i=ba.size()-1; i>=0; i--) {
4848                    boolean remove = false;
4849                    final int entUid = ba.keyAt(i);
4850                    if (name != null) {
4851                        if (userId == UserHandle.USER_ALL) {
4852                            if (UserHandle.getAppId(entUid) == appId) {
4853                                remove = true;
4854                            }
4855                        } else {
4856                            if (entUid == UserHandle.getUid(userId, appId)) {
4857                                remove = true;
4858                            }
4859                        }
4860                    } else if (UserHandle.getUserId(entUid) == userId) {
4861                        remove = true;
4862                    }
4863                    if (remove) {
4864                        ba.removeAt(i);
4865                    }
4866                }
4867                if (ba.size() == 0) {
4868                    pmap.removeAt(ip);
4869                }
4870            }
4871        }
4872
4873        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4874                -100, callerWillRestart, true, doit, evenPersistent,
4875                name == null ? ("stop user " + userId) : ("stop " + name));
4876
4877        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4878            if (!doit) {
4879                return true;
4880            }
4881            didSomething = true;
4882        }
4883
4884        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4885            if (!doit) {
4886                return true;
4887            }
4888            didSomething = true;
4889        }
4890
4891        if (name == null) {
4892            // Remove all sticky broadcasts from this user.
4893            mStickyBroadcasts.remove(userId);
4894        }
4895
4896        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4897        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4898                userId, providers)) {
4899            if (!doit) {
4900                return true;
4901            }
4902            didSomething = true;
4903        }
4904        N = providers.size();
4905        for (i=0; i<N; i++) {
4906            removeDyingProviderLocked(null, providers.get(i), true);
4907        }
4908
4909        // Remove transient permissions granted from/to this package/user
4910        removeUriPermissionsForPackageLocked(name, userId, false);
4911
4912        if (name == null || uninstalling) {
4913            // Remove pending intents.  For now we only do this when force
4914            // stopping users, because we have some problems when doing this
4915            // for packages -- app widgets are not currently cleaned up for
4916            // such packages, so they can be left with bad pending intents.
4917            if (mIntentSenderRecords.size() > 0) {
4918                Iterator<WeakReference<PendingIntentRecord>> it
4919                        = mIntentSenderRecords.values().iterator();
4920                while (it.hasNext()) {
4921                    WeakReference<PendingIntentRecord> wpir = it.next();
4922                    if (wpir == null) {
4923                        it.remove();
4924                        continue;
4925                    }
4926                    PendingIntentRecord pir = wpir.get();
4927                    if (pir == null) {
4928                        it.remove();
4929                        continue;
4930                    }
4931                    if (name == null) {
4932                        // Stopping user, remove all objects for the user.
4933                        if (pir.key.userId != userId) {
4934                            // Not the same user, skip it.
4935                            continue;
4936                        }
4937                    } else {
4938                        if (UserHandle.getAppId(pir.uid) != appId) {
4939                            // Different app id, skip it.
4940                            continue;
4941                        }
4942                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4943                            // Different user, skip it.
4944                            continue;
4945                        }
4946                        if (!pir.key.packageName.equals(name)) {
4947                            // Different package, skip it.
4948                            continue;
4949                        }
4950                    }
4951                    if (!doit) {
4952                        return true;
4953                    }
4954                    didSomething = true;
4955                    it.remove();
4956                    pir.canceled = true;
4957                    if (pir.key.activity != null) {
4958                        pir.key.activity.pendingResults.remove(pir.ref);
4959                    }
4960                }
4961            }
4962        }
4963
4964        if (doit) {
4965            if (purgeCache && name != null) {
4966                AttributeCache ac = AttributeCache.instance();
4967                if (ac != null) {
4968                    ac.removePackage(name);
4969                }
4970            }
4971            if (mBooted) {
4972                mStackSupervisor.resumeTopActivitiesLocked();
4973                mStackSupervisor.scheduleIdleLocked();
4974            }
4975        }
4976
4977        return didSomething;
4978    }
4979
4980    private final boolean removeProcessLocked(ProcessRecord app,
4981            boolean callerWillRestart, boolean allowRestart, String reason) {
4982        final String name = app.processName;
4983        final int uid = app.uid;
4984        if (DEBUG_PROCESSES) Slog.d(
4985            TAG, "Force removing proc " + app.toShortString() + " (" + name
4986            + "/" + uid + ")");
4987
4988        mProcessNames.remove(name, uid);
4989        mIsolatedProcesses.remove(app.uid);
4990        if (mHeavyWeightProcess == app) {
4991            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4992                    mHeavyWeightProcess.userId, 0));
4993            mHeavyWeightProcess = null;
4994        }
4995        boolean needRestart = false;
4996        if (app.pid > 0 && app.pid != MY_PID) {
4997            int pid = app.pid;
4998            synchronized (mPidsSelfLocked) {
4999                mPidsSelfLocked.remove(pid);
5000                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5001            }
5002            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5003                    app.processName, app.info.uid);
5004            if (app.isolated) {
5005                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5006            }
5007            killUnneededProcessLocked(app, reason);
5008            handleAppDiedLocked(app, true, allowRestart);
5009            removeLruProcessLocked(app);
5010
5011            if (app.persistent && !app.isolated) {
5012                if (!callerWillRestart) {
5013                    addAppLocked(app.info, false);
5014                } else {
5015                    needRestart = true;
5016                }
5017            }
5018        } else {
5019            mRemovedProcesses.add(app);
5020        }
5021
5022        return needRestart;
5023    }
5024
5025    private final void processStartTimedOutLocked(ProcessRecord app) {
5026        final int pid = app.pid;
5027        boolean gone = false;
5028        synchronized (mPidsSelfLocked) {
5029            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5030            if (knownApp != null && knownApp.thread == null) {
5031                mPidsSelfLocked.remove(pid);
5032                gone = true;
5033            }
5034        }
5035
5036        if (gone) {
5037            Slog.w(TAG, "Process " + app + " failed to attach");
5038            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5039                    pid, app.uid, app.processName);
5040            mProcessNames.remove(app.processName, app.uid);
5041            mIsolatedProcesses.remove(app.uid);
5042            if (mHeavyWeightProcess == app) {
5043                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5044                        mHeavyWeightProcess.userId, 0));
5045                mHeavyWeightProcess = null;
5046            }
5047            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5048                    app.processName, app.info.uid);
5049            if (app.isolated) {
5050                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5051            }
5052            // Take care of any launching providers waiting for this process.
5053            checkAppInLaunchingProvidersLocked(app, true);
5054            // Take care of any services that are waiting for the process.
5055            mServices.processStartTimedOutLocked(app);
5056            killUnneededProcessLocked(app, "start timeout");
5057            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5058                Slog.w(TAG, "Unattached app died before backup, skipping");
5059                try {
5060                    IBackupManager bm = IBackupManager.Stub.asInterface(
5061                            ServiceManager.getService(Context.BACKUP_SERVICE));
5062                    bm.agentDisconnected(app.info.packageName);
5063                } catch (RemoteException e) {
5064                    // Can't happen; the backup manager is local
5065                }
5066            }
5067            if (isPendingBroadcastProcessLocked(pid)) {
5068                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5069                skipPendingBroadcastLocked(pid);
5070            }
5071        } else {
5072            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5073        }
5074    }
5075
5076    private final boolean attachApplicationLocked(IApplicationThread thread,
5077            int pid) {
5078
5079        // Find the application record that is being attached...  either via
5080        // the pid if we are running in multiple processes, or just pull the
5081        // next app record if we are emulating process with anonymous threads.
5082        ProcessRecord app;
5083        if (pid != MY_PID && pid >= 0) {
5084            synchronized (mPidsSelfLocked) {
5085                app = mPidsSelfLocked.get(pid);
5086            }
5087        } else {
5088            app = null;
5089        }
5090
5091        if (app == null) {
5092            Slog.w(TAG, "No pending application record for pid " + pid
5093                    + " (IApplicationThread " + thread + "); dropping process");
5094            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5095            if (pid > 0 && pid != MY_PID) {
5096                Process.killProcessQuiet(pid);
5097            } else {
5098                try {
5099                    thread.scheduleExit();
5100                } catch (Exception e) {
5101                    // Ignore exceptions.
5102                }
5103            }
5104            return false;
5105        }
5106
5107        // If this application record is still attached to a previous
5108        // process, clean it up now.
5109        if (app.thread != null) {
5110            handleAppDiedLocked(app, true, true);
5111        }
5112
5113        // Tell the process all about itself.
5114
5115        if (localLOGV) Slog.v(
5116                TAG, "Binding process pid " + pid + " to record " + app);
5117
5118        final String processName = app.processName;
5119        try {
5120            AppDeathRecipient adr = new AppDeathRecipient(
5121                    app, pid, thread);
5122            thread.asBinder().linkToDeath(adr, 0);
5123            app.deathRecipient = adr;
5124        } catch (RemoteException e) {
5125            app.resetPackageList(mProcessStats);
5126            startProcessLocked(app, "link fail", processName);
5127            return false;
5128        }
5129
5130        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5131
5132        app.makeActive(thread, mProcessStats);
5133        app.curAdj = app.setAdj = -100;
5134        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5135        app.forcingToForeground = null;
5136        updateProcessForegroundLocked(app, false, false);
5137        app.hasShownUi = false;
5138        app.debugging = false;
5139        app.cached = false;
5140
5141        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5142
5143        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5144        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5145
5146        if (!normalMode) {
5147            Slog.i(TAG, "Launching preboot mode app: " + app);
5148        }
5149
5150        if (localLOGV) Slog.v(
5151            TAG, "New app record " + app
5152            + " thread=" + thread.asBinder() + " pid=" + pid);
5153        try {
5154            int testMode = IApplicationThread.DEBUG_OFF;
5155            if (mDebugApp != null && mDebugApp.equals(processName)) {
5156                testMode = mWaitForDebugger
5157                    ? IApplicationThread.DEBUG_WAIT
5158                    : IApplicationThread.DEBUG_ON;
5159                app.debugging = true;
5160                if (mDebugTransient) {
5161                    mDebugApp = mOrigDebugApp;
5162                    mWaitForDebugger = mOrigWaitForDebugger;
5163                }
5164            }
5165            String profileFile = app.instrumentationProfileFile;
5166            ParcelFileDescriptor profileFd = null;
5167            boolean profileAutoStop = false;
5168            if (mProfileApp != null && mProfileApp.equals(processName)) {
5169                mProfileProc = app;
5170                profileFile = mProfileFile;
5171                profileFd = mProfileFd;
5172                profileAutoStop = mAutoStopProfiler;
5173            }
5174            boolean enableOpenGlTrace = false;
5175            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5176                enableOpenGlTrace = true;
5177                mOpenGlTraceApp = null;
5178            }
5179
5180            // If the app is being launched for restore or full backup, set it up specially
5181            boolean isRestrictedBackupMode = false;
5182            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5183                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5184                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5185                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5186            }
5187
5188            ensurePackageDexOpt(app.instrumentationInfo != null
5189                    ? app.instrumentationInfo.packageName
5190                    : app.info.packageName);
5191            if (app.instrumentationClass != null) {
5192                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5193            }
5194            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5195                    + processName + " with config " + mConfiguration);
5196            ApplicationInfo appInfo = app.instrumentationInfo != null
5197                    ? app.instrumentationInfo : app.info;
5198            app.compat = compatibilityInfoForPackageLocked(appInfo);
5199            if (profileFd != null) {
5200                profileFd = profileFd.dup();
5201            }
5202            thread.bindApplication(processName, appInfo, providers,
5203                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5204                    app.instrumentationArguments, app.instrumentationWatcher,
5205                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5206                    isRestrictedBackupMode || !normalMode, app.persistent,
5207                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5208                    mCoreSettingsObserver.getCoreSettingsLocked());
5209            updateLruProcessLocked(app, false, null);
5210            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5211        } catch (Exception e) {
5212            // todo: Yikes!  What should we do?  For now we will try to
5213            // start another process, but that could easily get us in
5214            // an infinite loop of restarting processes...
5215            Slog.w(TAG, "Exception thrown during bind!", e);
5216
5217            app.resetPackageList(mProcessStats);
5218            app.unlinkDeathRecipient();
5219            startProcessLocked(app, "bind fail", processName);
5220            return false;
5221        }
5222
5223        // Remove this record from the list of starting applications.
5224        mPersistentStartingProcesses.remove(app);
5225        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5226                "Attach application locked removing on hold: " + app);
5227        mProcessesOnHold.remove(app);
5228
5229        boolean badApp = false;
5230        boolean didSomething = false;
5231
5232        // See if the top visible activity is waiting to run in this process...
5233        if (normalMode) {
5234            try {
5235                if (mStackSupervisor.attachApplicationLocked(app)) {
5236                    didSomething = true;
5237                }
5238            } catch (Exception e) {
5239                badApp = true;
5240            }
5241        }
5242
5243        // Find any services that should be running in this process...
5244        if (!badApp) {
5245            try {
5246                didSomething |= mServices.attachApplicationLocked(app, processName);
5247            } catch (Exception e) {
5248                badApp = true;
5249            }
5250        }
5251
5252        // Check if a next-broadcast receiver is in this process...
5253        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5254            try {
5255                didSomething |= sendPendingBroadcastsLocked(app);
5256            } catch (Exception e) {
5257                // If the app died trying to launch the receiver we declare it 'bad'
5258                badApp = true;
5259            }
5260        }
5261
5262        // Check whether the next backup agent is in this process...
5263        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5264            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5265            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5266            try {
5267                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5268                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5269                        mBackupTarget.backupMode);
5270            } catch (Exception e) {
5271                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5272                e.printStackTrace();
5273            }
5274        }
5275
5276        if (badApp) {
5277            // todo: Also need to kill application to deal with all
5278            // kinds of exceptions.
5279            handleAppDiedLocked(app, false, true);
5280            return false;
5281        }
5282
5283        if (!didSomething) {
5284            updateOomAdjLocked();
5285        }
5286
5287        return true;
5288    }
5289
5290    @Override
5291    public final void attachApplication(IApplicationThread thread) {
5292        synchronized (this) {
5293            int callingPid = Binder.getCallingPid();
5294            final long origId = Binder.clearCallingIdentity();
5295            attachApplicationLocked(thread, callingPid);
5296            Binder.restoreCallingIdentity(origId);
5297        }
5298    }
5299
5300    @Override
5301    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5302        final long origId = Binder.clearCallingIdentity();
5303        synchronized (this) {
5304            ActivityStack stack = ActivityRecord.getStackLocked(token);
5305            if (stack != null) {
5306                ActivityRecord r =
5307                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5308                if (stopProfiling) {
5309                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5310                        try {
5311                            mProfileFd.close();
5312                        } catch (IOException e) {
5313                        }
5314                        clearProfilerLocked();
5315                    }
5316                }
5317            }
5318        }
5319        Binder.restoreCallingIdentity(origId);
5320    }
5321
5322    void enableScreenAfterBoot() {
5323        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5324                SystemClock.uptimeMillis());
5325        mWindowManager.enableScreenAfterBoot();
5326
5327        synchronized (this) {
5328            updateEventDispatchingLocked();
5329        }
5330    }
5331
5332    @Override
5333    public void showBootMessage(final CharSequence msg, final boolean always) {
5334        enforceNotIsolatedCaller("showBootMessage");
5335        mWindowManager.showBootMessage(msg, always);
5336    }
5337
5338    @Override
5339    public void dismissKeyguardOnNextActivity() {
5340        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5341        final long token = Binder.clearCallingIdentity();
5342        try {
5343            synchronized (this) {
5344                if (DEBUG_LOCKSCREEN) logLockScreen("");
5345                if (mLockScreenShown) {
5346                    mLockScreenShown = false;
5347                    comeOutOfSleepIfNeededLocked();
5348                }
5349                mStackSupervisor.setDismissKeyguard(true);
5350            }
5351        } finally {
5352            Binder.restoreCallingIdentity(token);
5353        }
5354    }
5355
5356    final void finishBooting() {
5357        // Register receivers to handle package update events
5358        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5359
5360        synchronized (this) {
5361            // Ensure that any processes we had put on hold are now started
5362            // up.
5363            final int NP = mProcessesOnHold.size();
5364            if (NP > 0) {
5365                ArrayList<ProcessRecord> procs =
5366                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5367                for (int ip=0; ip<NP; ip++) {
5368                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5369                            + procs.get(ip));
5370                    startProcessLocked(procs.get(ip), "on-hold", null);
5371                }
5372            }
5373
5374            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5375                // Start looking for apps that are abusing wake locks.
5376                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5377                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5378                // Tell anyone interested that we are done booting!
5379                SystemProperties.set("sys.boot_completed", "1");
5380                SystemProperties.set("dev.bootcomplete", "1");
5381                for (int i=0; i<mStartedUsers.size(); i++) {
5382                    UserStartedState uss = mStartedUsers.valueAt(i);
5383                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5384                        uss.mState = UserStartedState.STATE_RUNNING;
5385                        final int userId = mStartedUsers.keyAt(i);
5386                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5387                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5388                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5389                        broadcastIntentLocked(null, null, intent, null,
5390                                new IIntentReceiver.Stub() {
5391                                    @Override
5392                                    public void performReceive(Intent intent, int resultCode,
5393                                            String data, Bundle extras, boolean ordered,
5394                                            boolean sticky, int sendingUser) {
5395                                        synchronized (ActivityManagerService.this) {
5396                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5397                                                    true, false);
5398                                        }
5399                                    }
5400                                },
5401                                0, null, null,
5402                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5403                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5404                                userId);
5405                    }
5406                }
5407                scheduleStartProfilesLocked();
5408            }
5409        }
5410    }
5411
5412    final void ensureBootCompleted() {
5413        boolean booting;
5414        boolean enableScreen;
5415        synchronized (this) {
5416            booting = mBooting;
5417            mBooting = false;
5418            enableScreen = !mBooted;
5419            mBooted = true;
5420        }
5421
5422        if (booting) {
5423            finishBooting();
5424        }
5425
5426        if (enableScreen) {
5427            enableScreenAfterBoot();
5428        }
5429    }
5430
5431    @Override
5432    public final void activityResumed(IBinder token) {
5433        final long origId = Binder.clearCallingIdentity();
5434        synchronized(this) {
5435            ActivityStack stack = ActivityRecord.getStackLocked(token);
5436            if (stack != null) {
5437                ActivityRecord.activityResumedLocked(token);
5438            }
5439        }
5440        Binder.restoreCallingIdentity(origId);
5441    }
5442
5443    @Override
5444    public final void activityPaused(IBinder token) {
5445        final long origId = Binder.clearCallingIdentity();
5446        synchronized(this) {
5447            ActivityStack stack = ActivityRecord.getStackLocked(token);
5448            if (stack != null) {
5449                stack.activityPausedLocked(token, false);
5450            }
5451        }
5452        Binder.restoreCallingIdentity(origId);
5453    }
5454
5455    @Override
5456    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5457            CharSequence description) {
5458        if (localLOGV) Slog.v(
5459            TAG, "Activity stopped: token=" + token);
5460
5461        // Refuse possible leaked file descriptors
5462        if (icicle != null && icicle.hasFileDescriptors()) {
5463            throw new IllegalArgumentException("File descriptors passed in Bundle");
5464        }
5465
5466        final long origId = Binder.clearCallingIdentity();
5467
5468        synchronized (this) {
5469            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5470            if (r != null) {
5471                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5472            }
5473        }
5474
5475        trimApplications();
5476
5477        Binder.restoreCallingIdentity(origId);
5478    }
5479
5480    @Override
5481    public final void activityDestroyed(IBinder token) {
5482        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5483        synchronized (this) {
5484            ActivityStack stack = ActivityRecord.getStackLocked(token);
5485            if (stack != null) {
5486                stack.activityDestroyedLocked(token);
5487            }
5488        }
5489    }
5490
5491    @Override
5492    public String getCallingPackage(IBinder token) {
5493        synchronized (this) {
5494            ActivityRecord r = getCallingRecordLocked(token);
5495            return r != null ? r.info.packageName : null;
5496        }
5497    }
5498
5499    @Override
5500    public ComponentName getCallingActivity(IBinder token) {
5501        synchronized (this) {
5502            ActivityRecord r = getCallingRecordLocked(token);
5503            return r != null ? r.intent.getComponent() : null;
5504        }
5505    }
5506
5507    private ActivityRecord getCallingRecordLocked(IBinder token) {
5508        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5509        if (r == null) {
5510            return null;
5511        }
5512        return r.resultTo;
5513    }
5514
5515    @Override
5516    public ComponentName getActivityClassForToken(IBinder token) {
5517        synchronized(this) {
5518            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5519            if (r == null) {
5520                return null;
5521            }
5522            return r.intent.getComponent();
5523        }
5524    }
5525
5526    @Override
5527    public String getPackageForToken(IBinder token) {
5528        synchronized(this) {
5529            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5530            if (r == null) {
5531                return null;
5532            }
5533            return r.packageName;
5534        }
5535    }
5536
5537    @Override
5538    public IIntentSender getIntentSender(int type,
5539            String packageName, IBinder token, String resultWho,
5540            int requestCode, Intent[] intents, String[] resolvedTypes,
5541            int flags, Bundle options, int userId) {
5542        enforceNotIsolatedCaller("getIntentSender");
5543        // Refuse possible leaked file descriptors
5544        if (intents != null) {
5545            if (intents.length < 1) {
5546                throw new IllegalArgumentException("Intents array length must be >= 1");
5547            }
5548            for (int i=0; i<intents.length; i++) {
5549                Intent intent = intents[i];
5550                if (intent != null) {
5551                    if (intent.hasFileDescriptors()) {
5552                        throw new IllegalArgumentException("File descriptors passed in Intent");
5553                    }
5554                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5555                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5556                        throw new IllegalArgumentException(
5557                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5558                    }
5559                    intents[i] = new Intent(intent);
5560                }
5561            }
5562            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5563                throw new IllegalArgumentException(
5564                        "Intent array length does not match resolvedTypes length");
5565            }
5566        }
5567        if (options != null) {
5568            if (options.hasFileDescriptors()) {
5569                throw new IllegalArgumentException("File descriptors passed in options");
5570            }
5571        }
5572
5573        synchronized(this) {
5574            int callingUid = Binder.getCallingUid();
5575            int origUserId = userId;
5576            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5577                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5578                    "getIntentSender", null);
5579            if (origUserId == UserHandle.USER_CURRENT) {
5580                // We don't want to evaluate this until the pending intent is
5581                // actually executed.  However, we do want to always do the
5582                // security checking for it above.
5583                userId = UserHandle.USER_CURRENT;
5584            }
5585            try {
5586                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5587                    int uid = AppGlobals.getPackageManager()
5588                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5589                    if (!UserHandle.isSameApp(callingUid, uid)) {
5590                        String msg = "Permission Denial: getIntentSender() from pid="
5591                            + Binder.getCallingPid()
5592                            + ", uid=" + Binder.getCallingUid()
5593                            + ", (need uid=" + uid + ")"
5594                            + " is not allowed to send as package " + packageName;
5595                        Slog.w(TAG, msg);
5596                        throw new SecurityException(msg);
5597                    }
5598                }
5599
5600                return getIntentSenderLocked(type, packageName, callingUid, userId,
5601                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5602
5603            } catch (RemoteException e) {
5604                throw new SecurityException(e);
5605            }
5606        }
5607    }
5608
5609    IIntentSender getIntentSenderLocked(int type, String packageName,
5610            int callingUid, int userId, IBinder token, String resultWho,
5611            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5612            Bundle options) {
5613        if (DEBUG_MU)
5614            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5615        ActivityRecord activity = null;
5616        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5617            activity = ActivityRecord.isInStackLocked(token);
5618            if (activity == null) {
5619                return null;
5620            }
5621            if (activity.finishing) {
5622                return null;
5623            }
5624        }
5625
5626        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5627        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5628        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5629        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5630                |PendingIntent.FLAG_UPDATE_CURRENT);
5631
5632        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5633                type, packageName, activity, resultWho,
5634                requestCode, intents, resolvedTypes, flags, options, userId);
5635        WeakReference<PendingIntentRecord> ref;
5636        ref = mIntentSenderRecords.get(key);
5637        PendingIntentRecord rec = ref != null ? ref.get() : null;
5638        if (rec != null) {
5639            if (!cancelCurrent) {
5640                if (updateCurrent) {
5641                    if (rec.key.requestIntent != null) {
5642                        rec.key.requestIntent.replaceExtras(intents != null ?
5643                                intents[intents.length - 1] : null);
5644                    }
5645                    if (intents != null) {
5646                        intents[intents.length-1] = rec.key.requestIntent;
5647                        rec.key.allIntents = intents;
5648                        rec.key.allResolvedTypes = resolvedTypes;
5649                    } else {
5650                        rec.key.allIntents = null;
5651                        rec.key.allResolvedTypes = null;
5652                    }
5653                }
5654                return rec;
5655            }
5656            rec.canceled = true;
5657            mIntentSenderRecords.remove(key);
5658        }
5659        if (noCreate) {
5660            return rec;
5661        }
5662        rec = new PendingIntentRecord(this, key, callingUid);
5663        mIntentSenderRecords.put(key, rec.ref);
5664        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5665            if (activity.pendingResults == null) {
5666                activity.pendingResults
5667                        = new HashSet<WeakReference<PendingIntentRecord>>();
5668            }
5669            activity.pendingResults.add(rec.ref);
5670        }
5671        return rec;
5672    }
5673
5674    @Override
5675    public void cancelIntentSender(IIntentSender sender) {
5676        if (!(sender instanceof PendingIntentRecord)) {
5677            return;
5678        }
5679        synchronized(this) {
5680            PendingIntentRecord rec = (PendingIntentRecord)sender;
5681            try {
5682                int uid = AppGlobals.getPackageManager()
5683                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5684                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5685                    String msg = "Permission Denial: cancelIntentSender() from pid="
5686                        + Binder.getCallingPid()
5687                        + ", uid=" + Binder.getCallingUid()
5688                        + " is not allowed to cancel packges "
5689                        + rec.key.packageName;
5690                    Slog.w(TAG, msg);
5691                    throw new SecurityException(msg);
5692                }
5693            } catch (RemoteException e) {
5694                throw new SecurityException(e);
5695            }
5696            cancelIntentSenderLocked(rec, true);
5697        }
5698    }
5699
5700    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5701        rec.canceled = true;
5702        mIntentSenderRecords.remove(rec.key);
5703        if (cleanActivity && rec.key.activity != null) {
5704            rec.key.activity.pendingResults.remove(rec.ref);
5705        }
5706    }
5707
5708    @Override
5709    public String getPackageForIntentSender(IIntentSender pendingResult) {
5710        if (!(pendingResult instanceof PendingIntentRecord)) {
5711            return null;
5712        }
5713        try {
5714            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5715            return res.key.packageName;
5716        } catch (ClassCastException e) {
5717        }
5718        return null;
5719    }
5720
5721    @Override
5722    public int getUidForIntentSender(IIntentSender sender) {
5723        if (sender instanceof PendingIntentRecord) {
5724            try {
5725                PendingIntentRecord res = (PendingIntentRecord)sender;
5726                return res.uid;
5727            } catch (ClassCastException e) {
5728            }
5729        }
5730        return -1;
5731    }
5732
5733    @Override
5734    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5735        if (!(pendingResult instanceof PendingIntentRecord)) {
5736            return false;
5737        }
5738        try {
5739            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5740            if (res.key.allIntents == null) {
5741                return false;
5742            }
5743            for (int i=0; i<res.key.allIntents.length; i++) {
5744                Intent intent = res.key.allIntents[i];
5745                if (intent.getPackage() != null && intent.getComponent() != null) {
5746                    return false;
5747                }
5748            }
5749            return true;
5750        } catch (ClassCastException e) {
5751        }
5752        return false;
5753    }
5754
5755    @Override
5756    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5757        if (!(pendingResult instanceof PendingIntentRecord)) {
5758            return false;
5759        }
5760        try {
5761            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5762            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5763                return true;
5764            }
5765            return false;
5766        } catch (ClassCastException e) {
5767        }
5768        return false;
5769    }
5770
5771    @Override
5772    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5773        if (!(pendingResult instanceof PendingIntentRecord)) {
5774            return null;
5775        }
5776        try {
5777            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5778            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5779        } catch (ClassCastException e) {
5780        }
5781        return null;
5782    }
5783
5784    @Override
5785    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5786        if (!(pendingResult instanceof PendingIntentRecord)) {
5787            return null;
5788        }
5789        try {
5790            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5791            Intent intent = res.key.requestIntent;
5792            if (intent != null) {
5793                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5794                        || res.lastTagPrefix.equals(prefix))) {
5795                    return res.lastTag;
5796                }
5797                res.lastTagPrefix = prefix;
5798                StringBuilder sb = new StringBuilder(128);
5799                if (prefix != null) {
5800                    sb.append(prefix);
5801                }
5802                if (intent.getAction() != null) {
5803                    sb.append(intent.getAction());
5804                } else if (intent.getComponent() != null) {
5805                    intent.getComponent().appendShortString(sb);
5806                } else {
5807                    sb.append("?");
5808                }
5809                return res.lastTag = sb.toString();
5810            }
5811        } catch (ClassCastException e) {
5812        }
5813        return null;
5814    }
5815
5816    @Override
5817    public void setProcessLimit(int max) {
5818        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5819                "setProcessLimit()");
5820        synchronized (this) {
5821            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5822            mProcessLimitOverride = max;
5823        }
5824        trimApplications();
5825    }
5826
5827    @Override
5828    public int getProcessLimit() {
5829        synchronized (this) {
5830            return mProcessLimitOverride;
5831        }
5832    }
5833
5834    void foregroundTokenDied(ForegroundToken token) {
5835        synchronized (ActivityManagerService.this) {
5836            synchronized (mPidsSelfLocked) {
5837                ForegroundToken cur
5838                    = mForegroundProcesses.get(token.pid);
5839                if (cur != token) {
5840                    return;
5841                }
5842                mForegroundProcesses.remove(token.pid);
5843                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5844                if (pr == null) {
5845                    return;
5846                }
5847                pr.forcingToForeground = null;
5848                updateProcessForegroundLocked(pr, false, false);
5849            }
5850            updateOomAdjLocked();
5851        }
5852    }
5853
5854    @Override
5855    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5856        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5857                "setProcessForeground()");
5858        synchronized(this) {
5859            boolean changed = false;
5860
5861            synchronized (mPidsSelfLocked) {
5862                ProcessRecord pr = mPidsSelfLocked.get(pid);
5863                if (pr == null && isForeground) {
5864                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5865                    return;
5866                }
5867                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5868                if (oldToken != null) {
5869                    oldToken.token.unlinkToDeath(oldToken, 0);
5870                    mForegroundProcesses.remove(pid);
5871                    if (pr != null) {
5872                        pr.forcingToForeground = null;
5873                    }
5874                    changed = true;
5875                }
5876                if (isForeground && token != null) {
5877                    ForegroundToken newToken = new ForegroundToken() {
5878                        @Override
5879                        public void binderDied() {
5880                            foregroundTokenDied(this);
5881                        }
5882                    };
5883                    newToken.pid = pid;
5884                    newToken.token = token;
5885                    try {
5886                        token.linkToDeath(newToken, 0);
5887                        mForegroundProcesses.put(pid, newToken);
5888                        pr.forcingToForeground = token;
5889                        changed = true;
5890                    } catch (RemoteException e) {
5891                        // If the process died while doing this, we will later
5892                        // do the cleanup with the process death link.
5893                    }
5894                }
5895            }
5896
5897            if (changed) {
5898                updateOomAdjLocked();
5899            }
5900        }
5901    }
5902
5903    // =========================================================
5904    // PERMISSIONS
5905    // =========================================================
5906
5907    static class PermissionController extends IPermissionController.Stub {
5908        ActivityManagerService mActivityManagerService;
5909        PermissionController(ActivityManagerService activityManagerService) {
5910            mActivityManagerService = activityManagerService;
5911        }
5912
5913        @Override
5914        public boolean checkPermission(String permission, int pid, int uid) {
5915            return mActivityManagerService.checkPermission(permission, pid,
5916                    uid) == PackageManager.PERMISSION_GRANTED;
5917        }
5918    }
5919
5920    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5921        @Override
5922        public int checkComponentPermission(String permission, int pid, int uid,
5923                int owningUid, boolean exported) {
5924            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5925                    owningUid, exported);
5926        }
5927
5928        @Override
5929        public Object getAMSLock() {
5930            return ActivityManagerService.this;
5931        }
5932    }
5933
5934    /**
5935     * This can be called with or without the global lock held.
5936     */
5937    int checkComponentPermission(String permission, int pid, int uid,
5938            int owningUid, boolean exported) {
5939        // We might be performing an operation on behalf of an indirect binder
5940        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5941        // client identity accordingly before proceeding.
5942        Identity tlsIdentity = sCallerIdentity.get();
5943        if (tlsIdentity != null) {
5944            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5945                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5946            uid = tlsIdentity.uid;
5947            pid = tlsIdentity.pid;
5948        }
5949
5950        if (pid == MY_PID) {
5951            return PackageManager.PERMISSION_GRANTED;
5952        }
5953
5954        return ActivityManager.checkComponentPermission(permission, uid,
5955                owningUid, exported);
5956    }
5957
5958    /**
5959     * As the only public entry point for permissions checking, this method
5960     * can enforce the semantic that requesting a check on a null global
5961     * permission is automatically denied.  (Internally a null permission
5962     * string is used when calling {@link #checkComponentPermission} in cases
5963     * when only uid-based security is needed.)
5964     *
5965     * This can be called with or without the global lock held.
5966     */
5967    @Override
5968    public int checkPermission(String permission, int pid, int uid) {
5969        if (permission == null) {
5970            return PackageManager.PERMISSION_DENIED;
5971        }
5972        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5973    }
5974
5975    /**
5976     * Binder IPC calls go through the public entry point.
5977     * This can be called with or without the global lock held.
5978     */
5979    int checkCallingPermission(String permission) {
5980        return checkPermission(permission,
5981                Binder.getCallingPid(),
5982                UserHandle.getAppId(Binder.getCallingUid()));
5983    }
5984
5985    /**
5986     * This can be called with or without the global lock held.
5987     */
5988    void enforceCallingPermission(String permission, String func) {
5989        if (checkCallingPermission(permission)
5990                == PackageManager.PERMISSION_GRANTED) {
5991            return;
5992        }
5993
5994        String msg = "Permission Denial: " + func + " from pid="
5995                + Binder.getCallingPid()
5996                + ", uid=" + Binder.getCallingUid()
5997                + " requires " + permission;
5998        Slog.w(TAG, msg);
5999        throw new SecurityException(msg);
6000    }
6001
6002    /**
6003     * Determine if UID is holding permissions required to access {@link Uri} in
6004     * the given {@link ProviderInfo}. Final permission checking is always done
6005     * in {@link ContentProvider}.
6006     */
6007    private final boolean checkHoldingPermissionsLocked(
6008            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6009        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6010                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6011
6012        if (pi.applicationInfo.uid == uid) {
6013            return true;
6014        } else if (!pi.exported) {
6015            return false;
6016        }
6017
6018        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6019        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6020        try {
6021            // check if target holds top-level <provider> permissions
6022            if (!readMet && pi.readPermission != null
6023                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6024                readMet = true;
6025            }
6026            if (!writeMet && pi.writePermission != null
6027                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6028                writeMet = true;
6029            }
6030
6031            // track if unprotected read/write is allowed; any denied
6032            // <path-permission> below removes this ability
6033            boolean allowDefaultRead = pi.readPermission == null;
6034            boolean allowDefaultWrite = pi.writePermission == null;
6035
6036            // check if target holds any <path-permission> that match uri
6037            final PathPermission[] pps = pi.pathPermissions;
6038            if (pps != null) {
6039                final String path = grantUri.uri.getPath();
6040                int i = pps.length;
6041                while (i > 0 && (!readMet || !writeMet)) {
6042                    i--;
6043                    PathPermission pp = pps[i];
6044                    if (pp.match(path)) {
6045                        if (!readMet) {
6046                            final String pprperm = pp.getReadPermission();
6047                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6048                                    + pprperm + " for " + pp.getPath()
6049                                    + ": match=" + pp.match(path)
6050                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6051                            if (pprperm != null) {
6052                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6053                                    readMet = true;
6054                                } else {
6055                                    allowDefaultRead = false;
6056                                }
6057                            }
6058                        }
6059                        if (!writeMet) {
6060                            final String ppwperm = pp.getWritePermission();
6061                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6062                                    + ppwperm + " for " + pp.getPath()
6063                                    + ": match=" + pp.match(path)
6064                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6065                            if (ppwperm != null) {
6066                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6067                                    writeMet = true;
6068                                } else {
6069                                    allowDefaultWrite = false;
6070                                }
6071                            }
6072                        }
6073                    }
6074                }
6075            }
6076
6077            // grant unprotected <provider> read/write, if not blocked by
6078            // <path-permission> above
6079            if (allowDefaultRead) readMet = true;
6080            if (allowDefaultWrite) writeMet = true;
6081
6082        } catch (RemoteException e) {
6083            return false;
6084        }
6085
6086        return readMet && writeMet;
6087    }
6088
6089    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6090        ProviderInfo pi = null;
6091        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6092        if (cpr != null) {
6093            pi = cpr.info;
6094        } else {
6095            try {
6096                pi = AppGlobals.getPackageManager().resolveContentProvider(
6097                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6098            } catch (RemoteException ex) {
6099            }
6100        }
6101        return pi;
6102    }
6103
6104    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6105        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6106        if (targetUris != null) {
6107            return targetUris.get(grantUri);
6108        }
6109        return null;
6110    }
6111
6112    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6113            String targetPkg, int targetUid, GrantUri grantUri) {
6114        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6115        if (targetUris == null) {
6116            targetUris = Maps.newArrayMap();
6117            mGrantedUriPermissions.put(targetUid, targetUris);
6118        }
6119
6120        UriPermission perm = targetUris.get(grantUri);
6121        if (perm == null) {
6122            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6123            targetUris.put(grantUri, perm);
6124        }
6125
6126        return perm;
6127    }
6128
6129    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6130            final int modeFlags) {
6131        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6132        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6133                : UriPermission.STRENGTH_OWNED;
6134
6135        // Root gets to do everything.
6136        if (uid == 0) {
6137            return true;
6138        }
6139
6140        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6141        if (perms == null) return false;
6142
6143        // First look for exact match
6144        final UriPermission exactPerm = perms.get(grantUri);
6145        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6146            return true;
6147        }
6148
6149        // No exact match, look for prefixes
6150        final int N = perms.size();
6151        for (int i = 0; i < N; i++) {
6152            final UriPermission perm = perms.valueAt(i);
6153            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6154                    && perm.getStrength(modeFlags) >= minStrength) {
6155                return true;
6156            }
6157        }
6158
6159        return false;
6160    }
6161
6162    @Override
6163    public int checkUriPermission(Uri uri, int pid, int uid,
6164            final int modeFlags, int userId) {
6165        enforceNotIsolatedCaller("checkUriPermission");
6166
6167        // Another redirected-binder-call permissions check as in
6168        // {@link checkComponentPermission}.
6169        Identity tlsIdentity = sCallerIdentity.get();
6170        if (tlsIdentity != null) {
6171            uid = tlsIdentity.uid;
6172            pid = tlsIdentity.pid;
6173        }
6174
6175        // Our own process gets to do everything.
6176        if (pid == MY_PID) {
6177            return PackageManager.PERMISSION_GRANTED;
6178        }
6179        synchronized (this) {
6180            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6181                    ? PackageManager.PERMISSION_GRANTED
6182                    : PackageManager.PERMISSION_DENIED;
6183        }
6184    }
6185
6186    /**
6187     * Check if the targetPkg can be granted permission to access uri by
6188     * the callingUid using the given modeFlags.  Throws a security exception
6189     * if callingUid is not allowed to do this.  Returns the uid of the target
6190     * if the URI permission grant should be performed; returns -1 if it is not
6191     * needed (for example targetPkg already has permission to access the URI).
6192     * If you already know the uid of the target, you can supply it in
6193     * lastTargetUid else set that to -1.
6194     */
6195    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6196            final int modeFlags, int lastTargetUid) {
6197        if (!Intent.isAccessUriMode(modeFlags)) {
6198            return -1;
6199        }
6200
6201        if (targetPkg != null) {
6202            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6203                    "Checking grant " + targetPkg + " permission to " + grantUri);
6204        }
6205
6206        final IPackageManager pm = AppGlobals.getPackageManager();
6207
6208        // If this is not a content: uri, we can't do anything with it.
6209        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6210            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6211                    "Can't grant URI permission for non-content URI: " + grantUri);
6212            return -1;
6213        }
6214
6215        final String authority = grantUri.uri.getAuthority();
6216        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6217        if (pi == null) {
6218            Slog.w(TAG, "No content provider found for permission check: " +
6219                    grantUri.uri.toSafeString());
6220            return -1;
6221        }
6222
6223        int targetUid = lastTargetUid;
6224        if (targetUid < 0 && targetPkg != null) {
6225            try {
6226                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6227                if (targetUid < 0) {
6228                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6229                            "Can't grant URI permission no uid for: " + targetPkg);
6230                    return -1;
6231                }
6232            } catch (RemoteException ex) {
6233                return -1;
6234            }
6235        }
6236
6237        if (targetUid >= 0) {
6238            // First...  does the target actually need this permission?
6239            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6240                // No need to grant the target this permission.
6241                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6242                        "Target " + targetPkg + " already has full permission to " + grantUri);
6243                return -1;
6244            }
6245        } else {
6246            // First...  there is no target package, so can anyone access it?
6247            boolean allowed = pi.exported;
6248            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6249                if (pi.readPermission != null) {
6250                    allowed = false;
6251                }
6252            }
6253            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6254                if (pi.writePermission != null) {
6255                    allowed = false;
6256                }
6257            }
6258            if (allowed) {
6259                return -1;
6260            }
6261        }
6262
6263        // Second...  is the provider allowing granting of URI permissions?
6264        if (!pi.grantUriPermissions) {
6265            throw new SecurityException("Provider " + pi.packageName
6266                    + "/" + pi.name
6267                    + " does not allow granting of Uri permissions (uri "
6268                    + grantUri + ")");
6269        }
6270        if (pi.uriPermissionPatterns != null) {
6271            final int N = pi.uriPermissionPatterns.length;
6272            boolean allowed = false;
6273            for (int i=0; i<N; i++) {
6274                if (pi.uriPermissionPatterns[i] != null
6275                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6276                    allowed = true;
6277                    break;
6278                }
6279            }
6280            if (!allowed) {
6281                throw new SecurityException("Provider " + pi.packageName
6282                        + "/" + pi.name
6283                        + " does not allow granting of permission to path of Uri "
6284                        + grantUri);
6285            }
6286        }
6287
6288        // Third...  does the caller itself have permission to access
6289        // this uri?
6290        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6291            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6292                // Require they hold a strong enough Uri permission
6293                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6294                    throw new SecurityException("Uid " + callingUid
6295                            + " does not have permission to uri " + grantUri);
6296                }
6297            }
6298        }
6299        return targetUid;
6300    }
6301
6302    @Override
6303    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6304            final int modeFlags, int userId) {
6305        enforceNotIsolatedCaller("checkGrantUriPermission");
6306        synchronized(this) {
6307            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6308                    new GrantUri(userId, uri, false), modeFlags, -1);
6309        }
6310    }
6311
6312    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6313            final int modeFlags, UriPermissionOwner owner) {
6314        if (!Intent.isAccessUriMode(modeFlags)) {
6315            return;
6316        }
6317
6318        // So here we are: the caller has the assumed permission
6319        // to the uri, and the target doesn't.  Let's now give this to
6320        // the target.
6321
6322        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6323                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6324
6325        final String authority = grantUri.uri.getAuthority();
6326        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6327        if (pi == null) {
6328            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6329            return;
6330        }
6331
6332        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6333            grantUri.prefix = true;
6334        }
6335        final UriPermission perm = findOrCreateUriPermissionLocked(
6336                pi.packageName, targetPkg, targetUid, grantUri);
6337        perm.grantModes(modeFlags, owner);
6338    }
6339
6340    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6341            final int modeFlags, UriPermissionOwner owner) {
6342        if (targetPkg == null) {
6343            throw new NullPointerException("targetPkg");
6344        }
6345
6346        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6347                -1);
6348        if (targetUid < 0) {
6349            return;
6350        }
6351
6352        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6353                owner);
6354    }
6355
6356    static class NeededUriGrants extends ArrayList<GrantUri> {
6357        final String targetPkg;
6358        final int targetUid;
6359        final int flags;
6360
6361        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6362            this.targetPkg = targetPkg;
6363            this.targetUid = targetUid;
6364            this.flags = flags;
6365        }
6366    }
6367
6368    /**
6369     * Like checkGrantUriPermissionLocked, but takes an Intent.
6370     */
6371    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6372            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6373        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6374                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6375                + " clip=" + (intent != null ? intent.getClipData() : null)
6376                + " from " + intent + "; flags=0x"
6377                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6378
6379        if (targetPkg == null) {
6380            throw new NullPointerException("targetPkg");
6381        }
6382
6383        if (intent == null) {
6384            return null;
6385        }
6386        Uri data = intent.getData();
6387        ClipData clip = intent.getClipData();
6388        if (data == null && clip == null) {
6389            return null;
6390        }
6391
6392        if (data != null) {
6393            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6394            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6395                    needed != null ? needed.targetUid : -1);
6396            if (targetUid > 0) {
6397                if (needed == null) {
6398                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6399                }
6400                needed.add(grantUri);
6401            }
6402        }
6403        if (clip != null) {
6404            for (int i=0; i<clip.getItemCount(); i++) {
6405                Uri uri = clip.getItemAt(i).getUri();
6406                if (uri != null) {
6407                    int targetUid = -1;
6408                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6409                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6410                            needed != null ? needed.targetUid : -1);
6411                    if (targetUid > 0) {
6412                        if (needed == null) {
6413                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6414                        }
6415                        needed.add(grantUri);
6416                    }
6417                } else {
6418                    Intent clipIntent = clip.getItemAt(i).getIntent();
6419                    if (clipIntent != null) {
6420                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6421                                callingUid, targetPkg, clipIntent, mode, needed);
6422                        if (newNeeded != null) {
6423                            needed = newNeeded;
6424                        }
6425                    }
6426                }
6427            }
6428        }
6429
6430        return needed;
6431    }
6432
6433    /**
6434     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6435     */
6436    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6437            UriPermissionOwner owner) {
6438        if (needed != null) {
6439            for (int i=0; i<needed.size(); i++) {
6440                GrantUri grantUri = needed.get(i);
6441                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6442                        grantUri, needed.flags, owner);
6443            }
6444        }
6445    }
6446
6447    void grantUriPermissionFromIntentLocked(int callingUid,
6448            String targetPkg, Intent intent, UriPermissionOwner owner) {
6449        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6450                intent, intent != null ? intent.getFlags() : 0, null);
6451        if (needed == null) {
6452            return;
6453        }
6454
6455        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6456    }
6457
6458    @Override
6459    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6460            final int modeFlags, int userId) {
6461        enforceNotIsolatedCaller("grantUriPermission");
6462        GrantUri grantUri = new GrantUri(userId, uri, false);
6463        synchronized(this) {
6464            final ProcessRecord r = getRecordForAppLocked(caller);
6465            if (r == null) {
6466                throw new SecurityException("Unable to find app for caller "
6467                        + caller
6468                        + " when granting permission to uri " + grantUri);
6469            }
6470            if (targetPkg == null) {
6471                throw new IllegalArgumentException("null target");
6472            }
6473            if (grantUri == null) {
6474                throw new IllegalArgumentException("null uri");
6475            }
6476
6477            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6478                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6479                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6480                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6481
6482            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6483        }
6484    }
6485
6486    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6487        if (perm.modeFlags == 0) {
6488            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6489                    perm.targetUid);
6490            if (perms != null) {
6491                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6492                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6493
6494                perms.remove(perm.uri);
6495                if (perms.isEmpty()) {
6496                    mGrantedUriPermissions.remove(perm.targetUid);
6497                }
6498            }
6499        }
6500    }
6501
6502    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6503        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6504
6505        final IPackageManager pm = AppGlobals.getPackageManager();
6506        final String authority = grantUri.uri.getAuthority();
6507        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6508        if (pi == null) {
6509            Slog.w(TAG, "No content provider found for permission revoke: "
6510                    + grantUri.toSafeString());
6511            return;
6512        }
6513
6514        // Does the caller have this permission on the URI?
6515        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6516            // Right now, if you are not the original owner of the permission,
6517            // you are not allowed to revoke it.
6518            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6519                throw new SecurityException("Uid " + callingUid
6520                        + " does not have permission to uri " + grantUri);
6521            //}
6522        }
6523
6524        boolean persistChanged = false;
6525
6526        // Go through all of the permissions and remove any that match.
6527        int N = mGrantedUriPermissions.size();
6528        for (int i = 0; i < N; i++) {
6529            final int targetUid = mGrantedUriPermissions.keyAt(i);
6530            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6531
6532            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6533                final UriPermission perm = it.next();
6534                if (perm.uri.sourceUserId == grantUri.sourceUserId
6535                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6536                    if (DEBUG_URI_PERMISSION)
6537                        Slog.v(TAG,
6538                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6539                    persistChanged |= perm.revokeModes(
6540                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6541                    if (perm.modeFlags == 0) {
6542                        it.remove();
6543                    }
6544                }
6545            }
6546
6547            if (perms.isEmpty()) {
6548                mGrantedUriPermissions.remove(targetUid);
6549                N--;
6550                i--;
6551            }
6552        }
6553
6554        if (persistChanged) {
6555            schedulePersistUriGrants();
6556        }
6557    }
6558
6559    @Override
6560    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6561            int userId) {
6562        enforceNotIsolatedCaller("revokeUriPermission");
6563        synchronized(this) {
6564            final ProcessRecord r = getRecordForAppLocked(caller);
6565            if (r == null) {
6566                throw new SecurityException("Unable to find app for caller "
6567                        + caller
6568                        + " when revoking permission to uri " + uri);
6569            }
6570            if (uri == null) {
6571                Slog.w(TAG, "revokeUriPermission: null uri");
6572                return;
6573            }
6574
6575            if (!Intent.isAccessUriMode(modeFlags)) {
6576                return;
6577            }
6578
6579            final IPackageManager pm = AppGlobals.getPackageManager();
6580            final String authority = uri.getAuthority();
6581            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6582            if (pi == null) {
6583                Slog.w(TAG, "No content provider found for permission revoke: "
6584                        + uri.toSafeString());
6585                return;
6586            }
6587
6588            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6589        }
6590    }
6591
6592    /**
6593     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6594     * given package.
6595     *
6596     * @param packageName Package name to match, or {@code null} to apply to all
6597     *            packages.
6598     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6599     *            to all users.
6600     * @param persistable If persistable grants should be removed.
6601     */
6602    private void removeUriPermissionsForPackageLocked(
6603            String packageName, int userHandle, boolean persistable) {
6604        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6605            throw new IllegalArgumentException("Must narrow by either package or user");
6606        }
6607
6608        boolean persistChanged = false;
6609
6610        int N = mGrantedUriPermissions.size();
6611        for (int i = 0; i < N; i++) {
6612            final int targetUid = mGrantedUriPermissions.keyAt(i);
6613            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6614
6615            // Only inspect grants matching user
6616            if (userHandle == UserHandle.USER_ALL
6617                    || userHandle == UserHandle.getUserId(targetUid)) {
6618                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6619                    final UriPermission perm = it.next();
6620
6621                    // Only inspect grants matching package
6622                    if (packageName == null || perm.sourcePkg.equals(packageName)
6623                            || perm.targetPkg.equals(packageName)) {
6624                        persistChanged |= perm.revokeModes(
6625                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6626
6627                        // Only remove when no modes remain; any persisted grants
6628                        // will keep this alive.
6629                        if (perm.modeFlags == 0) {
6630                            it.remove();
6631                        }
6632                    }
6633                }
6634
6635                if (perms.isEmpty()) {
6636                    mGrantedUriPermissions.remove(targetUid);
6637                    N--;
6638                    i--;
6639                }
6640            }
6641        }
6642
6643        if (persistChanged) {
6644            schedulePersistUriGrants();
6645        }
6646    }
6647
6648    @Override
6649    public IBinder newUriPermissionOwner(String name) {
6650        enforceNotIsolatedCaller("newUriPermissionOwner");
6651        synchronized(this) {
6652            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6653            return owner.getExternalTokenLocked();
6654        }
6655    }
6656
6657    @Override
6658    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6659            final int modeFlags, int userId) {
6660        synchronized(this) {
6661            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6662            if (owner == null) {
6663                throw new IllegalArgumentException("Unknown owner: " + token);
6664            }
6665            if (fromUid != Binder.getCallingUid()) {
6666                if (Binder.getCallingUid() != Process.myUid()) {
6667                    // Only system code can grant URI permissions on behalf
6668                    // of other users.
6669                    throw new SecurityException("nice try");
6670                }
6671            }
6672            if (targetPkg == null) {
6673                throw new IllegalArgumentException("null target");
6674            }
6675            if (uri == null) {
6676                throw new IllegalArgumentException("null uri");
6677            }
6678
6679            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6680                    modeFlags, owner);
6681        }
6682    }
6683
6684    @Override
6685    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6686        synchronized(this) {
6687            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6688            if (owner == null) {
6689                throw new IllegalArgumentException("Unknown owner: " + token);
6690            }
6691
6692            if (uri == null) {
6693                owner.removeUriPermissionsLocked(mode);
6694            } else {
6695                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6696            }
6697        }
6698    }
6699
6700    private void schedulePersistUriGrants() {
6701        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6702            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6703                    10 * DateUtils.SECOND_IN_MILLIS);
6704        }
6705    }
6706
6707    private void writeGrantedUriPermissions() {
6708        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6709
6710        // Snapshot permissions so we can persist without lock
6711        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6712        synchronized (this) {
6713            final int size = mGrantedUriPermissions.size();
6714            for (int i = 0; i < size; i++) {
6715                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6716                for (UriPermission perm : perms.values()) {
6717                    if (perm.persistedModeFlags != 0) {
6718                        persist.add(perm.snapshot());
6719                    }
6720                }
6721            }
6722        }
6723
6724        FileOutputStream fos = null;
6725        try {
6726            fos = mGrantFile.startWrite();
6727
6728            XmlSerializer out = new FastXmlSerializer();
6729            out.setOutput(fos, "utf-8");
6730            out.startDocument(null, true);
6731            out.startTag(null, TAG_URI_GRANTS);
6732            for (UriPermission.Snapshot perm : persist) {
6733                out.startTag(null, TAG_URI_GRANT);
6734                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6735                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6736                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6737                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6738                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6739                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6740                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6741                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6742                out.endTag(null, TAG_URI_GRANT);
6743            }
6744            out.endTag(null, TAG_URI_GRANTS);
6745            out.endDocument();
6746
6747            mGrantFile.finishWrite(fos);
6748        } catch (IOException e) {
6749            if (fos != null) {
6750                mGrantFile.failWrite(fos);
6751            }
6752        }
6753    }
6754
6755    private void readGrantedUriPermissionsLocked() {
6756        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6757
6758        final long now = System.currentTimeMillis();
6759
6760        FileInputStream fis = null;
6761        try {
6762            fis = mGrantFile.openRead();
6763            final XmlPullParser in = Xml.newPullParser();
6764            in.setInput(fis, null);
6765
6766            int type;
6767            while ((type = in.next()) != END_DOCUMENT) {
6768                final String tag = in.getName();
6769                if (type == START_TAG) {
6770                    if (TAG_URI_GRANT.equals(tag)) {
6771                        final int sourceUserId;
6772                        final int targetUserId;
6773                        final int userHandle = readIntAttribute(in,
6774                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6775                        if (userHandle != UserHandle.USER_NULL) {
6776                            // For backwards compatibility.
6777                            sourceUserId = userHandle;
6778                            targetUserId = userHandle;
6779                        } else {
6780                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6781                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6782                        }
6783                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6784                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6785                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6786                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6787                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6788                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6789
6790                        // Sanity check that provider still belongs to source package
6791                        final ProviderInfo pi = getProviderInfoLocked(
6792                                uri.getAuthority(), sourceUserId);
6793                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6794                            int targetUid = -1;
6795                            try {
6796                                targetUid = AppGlobals.getPackageManager()
6797                                        .getPackageUid(targetPkg, targetUserId);
6798                            } catch (RemoteException e) {
6799                            }
6800                            if (targetUid != -1) {
6801                                final UriPermission perm = findOrCreateUriPermissionLocked(
6802                                        sourcePkg, targetPkg, targetUid,
6803                                        new GrantUri(sourceUserId, uri, prefix));
6804                                perm.initPersistedModes(modeFlags, createdTime);
6805                            }
6806                        } else {
6807                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6808                                    + " but instead found " + pi);
6809                        }
6810                    }
6811                }
6812            }
6813        } catch (FileNotFoundException e) {
6814            // Missing grants is okay
6815        } catch (IOException e) {
6816            Log.wtf(TAG, "Failed reading Uri grants", e);
6817        } catch (XmlPullParserException e) {
6818            Log.wtf(TAG, "Failed reading Uri grants", e);
6819        } finally {
6820            IoUtils.closeQuietly(fis);
6821        }
6822    }
6823
6824    @Override
6825    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6826        enforceNotIsolatedCaller("takePersistableUriPermission");
6827
6828        Preconditions.checkFlagsArgument(modeFlags,
6829                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6830
6831        synchronized (this) {
6832            final int callingUid = Binder.getCallingUid();
6833            boolean persistChanged = false;
6834            GrantUri grantUri = new GrantUri(userId, uri, false);
6835
6836            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6837                    new GrantUri(userId, uri, false));
6838            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6839                    new GrantUri(userId, uri, true));
6840
6841            final boolean exactValid = (exactPerm != null)
6842                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6843            final boolean prefixValid = (prefixPerm != null)
6844                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6845
6846            if (!(exactValid || prefixValid)) {
6847                throw new SecurityException("No persistable permission grants found for UID "
6848                        + callingUid + " and Uri " + grantUri.toSafeString());
6849            }
6850
6851            if (exactValid) {
6852                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6853            }
6854            if (prefixValid) {
6855                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6856            }
6857
6858            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6859
6860            if (persistChanged) {
6861                schedulePersistUriGrants();
6862            }
6863        }
6864    }
6865
6866    @Override
6867    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6868        enforceNotIsolatedCaller("releasePersistableUriPermission");
6869
6870        Preconditions.checkFlagsArgument(modeFlags,
6871                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6872
6873        synchronized (this) {
6874            final int callingUid = Binder.getCallingUid();
6875            boolean persistChanged = false;
6876
6877            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6878                    new GrantUri(userId, uri, false));
6879            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6880                    new GrantUri(userId, uri, true));
6881            if (exactPerm == null && prefixPerm == null) {
6882                throw new SecurityException("No permission grants found for UID " + callingUid
6883                        + " and Uri " + uri.toSafeString());
6884            }
6885
6886            if (exactPerm != null) {
6887                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6888                removeUriPermissionIfNeededLocked(exactPerm);
6889            }
6890            if (prefixPerm != null) {
6891                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6892                removeUriPermissionIfNeededLocked(prefixPerm);
6893            }
6894
6895            if (persistChanged) {
6896                schedulePersistUriGrants();
6897            }
6898        }
6899    }
6900
6901    /**
6902     * Prune any older {@link UriPermission} for the given UID until outstanding
6903     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6904     *
6905     * @return if any mutations occured that require persisting.
6906     */
6907    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6908        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6909        if (perms == null) return false;
6910        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6911
6912        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6913        for (UriPermission perm : perms.values()) {
6914            if (perm.persistedModeFlags != 0) {
6915                persisted.add(perm);
6916            }
6917        }
6918
6919        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6920        if (trimCount <= 0) return false;
6921
6922        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6923        for (int i = 0; i < trimCount; i++) {
6924            final UriPermission perm = persisted.get(i);
6925
6926            if (DEBUG_URI_PERMISSION) {
6927                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6928            }
6929
6930            perm.releasePersistableModes(~0);
6931            removeUriPermissionIfNeededLocked(perm);
6932        }
6933
6934        return true;
6935    }
6936
6937    @Override
6938    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6939            String packageName, boolean incoming) {
6940        enforceNotIsolatedCaller("getPersistedUriPermissions");
6941        Preconditions.checkNotNull(packageName, "packageName");
6942
6943        final int callingUid = Binder.getCallingUid();
6944        final IPackageManager pm = AppGlobals.getPackageManager();
6945        try {
6946            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6947            if (packageUid != callingUid) {
6948                throw new SecurityException(
6949                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6950            }
6951        } catch (RemoteException e) {
6952            throw new SecurityException("Failed to verify package name ownership");
6953        }
6954
6955        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6956        synchronized (this) {
6957            if (incoming) {
6958                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6959                        callingUid);
6960                if (perms == null) {
6961                    Slog.w(TAG, "No permission grants found for " + packageName);
6962                } else {
6963                    for (UriPermission perm : perms.values()) {
6964                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6965                            result.add(perm.buildPersistedPublicApiObject());
6966                        }
6967                    }
6968                }
6969            } else {
6970                final int size = mGrantedUriPermissions.size();
6971                for (int i = 0; i < size; i++) {
6972                    final ArrayMap<GrantUri, UriPermission> perms =
6973                            mGrantedUriPermissions.valueAt(i);
6974                    for (UriPermission perm : perms.values()) {
6975                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6976                            result.add(perm.buildPersistedPublicApiObject());
6977                        }
6978                    }
6979                }
6980            }
6981        }
6982        return new ParceledListSlice<android.content.UriPermission>(result);
6983    }
6984
6985    @Override
6986    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6987        synchronized (this) {
6988            ProcessRecord app =
6989                who != null ? getRecordForAppLocked(who) : null;
6990            if (app == null) return;
6991
6992            Message msg = Message.obtain();
6993            msg.what = WAIT_FOR_DEBUGGER_MSG;
6994            msg.obj = app;
6995            msg.arg1 = waiting ? 1 : 0;
6996            mHandler.sendMessage(msg);
6997        }
6998    }
6999
7000    @Override
7001    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7002        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7003        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7004        outInfo.availMem = Process.getFreeMemory();
7005        outInfo.totalMem = Process.getTotalMemory();
7006        outInfo.threshold = homeAppMem;
7007        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7008        outInfo.hiddenAppThreshold = cachedAppMem;
7009        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7010                ProcessList.SERVICE_ADJ);
7011        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7012                ProcessList.VISIBLE_APP_ADJ);
7013        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7014                ProcessList.FOREGROUND_APP_ADJ);
7015    }
7016
7017    // =========================================================
7018    // TASK MANAGEMENT
7019    // =========================================================
7020
7021    @Override
7022    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7023        final int callingUid = Binder.getCallingUid();
7024        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7025
7026        synchronized(this) {
7027            if (localLOGV) Slog.v(
7028                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7029
7030            final boolean allowed = checkCallingPermission(
7031                    android.Manifest.permission.GET_TASKS)
7032                    == PackageManager.PERMISSION_GRANTED;
7033            if (!allowed) {
7034                Slog.w(TAG, "getTasks: caller " + callingUid
7035                        + " does not hold GET_TASKS; limiting output");
7036            }
7037
7038            // TODO: Improve with MRU list from all ActivityStacks.
7039            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7040        }
7041
7042        return list;
7043    }
7044
7045    TaskRecord getMostRecentTask() {
7046        return mRecentTasks.get(0);
7047    }
7048
7049    @Override
7050    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7051            int flags, int userId) {
7052        final int callingUid = Binder.getCallingUid();
7053        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7054                false, true, "getRecentTasks", null);
7055
7056        synchronized (this) {
7057            final boolean allowed = checkCallingPermission(
7058                    android.Manifest.permission.GET_TASKS)
7059                    == PackageManager.PERMISSION_GRANTED;
7060            if (!allowed) {
7061                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7062                        + " does not hold GET_TASKS; limiting output");
7063            }
7064            final boolean detailed = checkCallingPermission(
7065                    android.Manifest.permission.GET_DETAILED_TASKS)
7066                    == PackageManager.PERMISSION_GRANTED;
7067
7068            IPackageManager pm = AppGlobals.getPackageManager();
7069
7070            final int N = mRecentTasks.size();
7071            ArrayList<ActivityManager.RecentTaskInfo> res
7072                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7073                            maxNum < N ? maxNum : N);
7074
7075            final Set<Integer> includedUsers;
7076            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7077                includedUsers = getProfileIdsLocked(userId);
7078            } else {
7079                includedUsers = new HashSet<Integer>();
7080            }
7081            includedUsers.add(Integer.valueOf(userId));
7082            for (int i=0; i<N && maxNum > 0; i++) {
7083                TaskRecord tr = mRecentTasks.get(i);
7084                // Only add calling user or related users recent tasks
7085                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7086
7087                // Return the entry if desired by the caller.  We always return
7088                // the first entry, because callers always expect this to be the
7089                // foreground app.  We may filter others if the caller has
7090                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7091                // we should exclude the entry.
7092
7093                if (i == 0
7094                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7095                        || (tr.intent == null)
7096                        || ((tr.intent.getFlags()
7097                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7098                    if (!allowed) {
7099                        // If the caller doesn't have the GET_TASKS permission, then only
7100                        // allow them to see a small subset of tasks -- their own and home.
7101                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7102                            continue;
7103                        }
7104                    }
7105                    ActivityManager.RecentTaskInfo rti
7106                            = new ActivityManager.RecentTaskInfo();
7107                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7108                    rti.persistentId = tr.taskId;
7109                    rti.baseIntent = new Intent(
7110                            tr.intent != null ? tr.intent : tr.affinityIntent);
7111                    if (!detailed) {
7112                        rti.baseIntent.replaceExtras((Bundle)null);
7113                    }
7114                    rti.origActivity = tr.origActivity;
7115                    rti.description = tr.lastDescription;
7116                    rti.stackId = tr.stack.mStackId;
7117                    rti.userId = tr.userId;
7118
7119                    // Traverse upwards looking for any break between main task activities and
7120                    // utility activities.
7121                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7122                    int activityNdx;
7123                    final int numActivities = activities.size();
7124                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7125                            ++activityNdx) {
7126                        final ActivityRecord r = activities.get(activityNdx);
7127                        if (r.intent != null &&
7128                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7129                                        != 0) {
7130                            break;
7131                        }
7132                    }
7133                    if (activityNdx > 0) {
7134                        // Traverse downwards starting below break looking for set label, icon.
7135                        // Note that if there are activities in the task but none of them set the
7136                        // recent activity values, then we do not fall back to the last set
7137                        // values in the TaskRecord.
7138                        rti.activityValues = new ActivityManager.RecentsActivityValues();
7139                        for (--activityNdx; activityNdx >= 0; --activityNdx) {
7140                            final ActivityRecord r = activities.get(activityNdx);
7141                            if (r.activityValues != null) {
7142                                if (rti.activityValues.label == null) {
7143                                    rti.activityValues.label = r.activityValues.label;
7144                                    tr.lastActivityValues.label = r.activityValues.label;
7145                                }
7146                                if (rti.activityValues.icon == null) {
7147                                    rti.activityValues.icon = r.activityValues.icon;
7148                                    tr.lastActivityValues.icon = r.activityValues.icon;
7149                                }
7150                                if (rti.activityValues.colorPrimary == 0) {
7151                                    rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7152                                    tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7153                                }
7154                            }
7155                        }
7156                    } else {
7157                        // If there are no activity records in this task, then we use the last
7158                        // resolved values
7159                        rti.activityValues =
7160                                new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7161                    }
7162
7163                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7164                        // Check whether this activity is currently available.
7165                        try {
7166                            if (rti.origActivity != null) {
7167                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7168                                        == null) {
7169                                    continue;
7170                                }
7171                            } else if (rti.baseIntent != null) {
7172                                if (pm.queryIntentActivities(rti.baseIntent,
7173                                        null, 0, userId) == null) {
7174                                    continue;
7175                                }
7176                            }
7177                        } catch (RemoteException e) {
7178                            // Will never happen.
7179                        }
7180                    }
7181
7182                    res.add(rti);
7183                    maxNum--;
7184                }
7185            }
7186            return res;
7187        }
7188    }
7189
7190    private TaskRecord recentTaskForIdLocked(int id) {
7191        final int N = mRecentTasks.size();
7192            for (int i=0; i<N; i++) {
7193                TaskRecord tr = mRecentTasks.get(i);
7194                if (tr.taskId == id) {
7195                    return tr;
7196                }
7197            }
7198            return null;
7199    }
7200
7201    @Override
7202    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7203        synchronized (this) {
7204            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7205                    "getTaskThumbnails()");
7206            TaskRecord tr = recentTaskForIdLocked(id);
7207            if (tr != null) {
7208                return tr.getTaskThumbnailsLocked();
7209            }
7210        }
7211        return null;
7212    }
7213
7214    @Override
7215    public Bitmap getTaskTopThumbnail(int id) {
7216        synchronized (this) {
7217            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7218                    "getTaskTopThumbnail()");
7219            TaskRecord tr = recentTaskForIdLocked(id);
7220            if (tr != null) {
7221                return tr.getTaskTopThumbnailLocked();
7222            }
7223        }
7224        return null;
7225    }
7226
7227    @Override
7228    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7229        synchronized (this) {
7230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7231            if (r != null) {
7232                r.activityValues = rav;
7233            }
7234        }
7235    }
7236
7237    @Override
7238    public boolean removeSubTask(int taskId, int subTaskIndex) {
7239        synchronized (this) {
7240            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7241                    "removeSubTask()");
7242            long ident = Binder.clearCallingIdentity();
7243            try {
7244                TaskRecord tr = recentTaskForIdLocked(taskId);
7245                if (tr != null) {
7246                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7247                }
7248                return false;
7249            } finally {
7250                Binder.restoreCallingIdentity(ident);
7251            }
7252        }
7253    }
7254
7255    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7256        if (!pr.killedByAm) {
7257            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7258            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7259                    pr.processName, pr.setAdj, reason);
7260            pr.killedByAm = true;
7261            Process.killProcessQuiet(pr.pid);
7262        }
7263    }
7264
7265    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7266        tr.disposeThumbnail();
7267        mRecentTasks.remove(tr);
7268        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7269        Intent baseIntent = new Intent(
7270                tr.intent != null ? tr.intent : tr.affinityIntent);
7271        ComponentName component = baseIntent.getComponent();
7272        if (component == null) {
7273            Slog.w(TAG, "Now component for base intent of task: " + tr);
7274            return;
7275        }
7276
7277        // Find any running services associated with this app.
7278        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7279
7280        if (killProcesses) {
7281            // Find any running processes associated with this app.
7282            final String pkg = component.getPackageName();
7283            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7284            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7285            for (int i=0; i<pmap.size(); i++) {
7286                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7287                for (int j=0; j<uids.size(); j++) {
7288                    ProcessRecord proc = uids.valueAt(j);
7289                    if (proc.userId != tr.userId) {
7290                        continue;
7291                    }
7292                    if (!proc.pkgList.containsKey(pkg)) {
7293                        continue;
7294                    }
7295                    procs.add(proc);
7296                }
7297            }
7298
7299            // Kill the running processes.
7300            for (int i=0; i<procs.size(); i++) {
7301                ProcessRecord pr = procs.get(i);
7302                if (pr == mHomeProcess) {
7303                    // Don't kill the home process along with tasks from the same package.
7304                    continue;
7305                }
7306                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7307                    killUnneededProcessLocked(pr, "remove task");
7308                } else {
7309                    pr.waitingToKill = "remove task";
7310                }
7311            }
7312        }
7313    }
7314
7315    /**
7316     * Removes the task with the specified task id.
7317     *
7318     * @param taskId Identifier of the task to be removed.
7319     * @param flags Additional operational flags.  May be 0 or
7320     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7321     * @return Returns true if the given task was found and removed.
7322     */
7323    private boolean removeTaskByIdLocked(int taskId, int flags) {
7324        TaskRecord tr = recentTaskForIdLocked(taskId);
7325        if (tr != null) {
7326            tr.removeTaskActivitiesLocked(-1, false);
7327            cleanUpRemovedTaskLocked(tr, flags);
7328            return true;
7329        }
7330        return false;
7331    }
7332
7333    @Override
7334    public boolean removeTask(int taskId, int flags) {
7335        synchronized (this) {
7336            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7337                    "removeTask()");
7338            long ident = Binder.clearCallingIdentity();
7339            try {
7340                return removeTaskByIdLocked(taskId, flags);
7341            } finally {
7342                Binder.restoreCallingIdentity(ident);
7343            }
7344        }
7345    }
7346
7347    /**
7348     * TODO: Add mController hook
7349     */
7350    @Override
7351    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7352        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7353                "moveTaskToFront()");
7354
7355        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7356        synchronized(this) {
7357            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7358                    Binder.getCallingUid(), "Task to front")) {
7359                ActivityOptions.abort(options);
7360                return;
7361            }
7362            final long origId = Binder.clearCallingIdentity();
7363            try {
7364                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7365                if (task == null) {
7366                    return;
7367                }
7368                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7369                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7370                    return;
7371                }
7372                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7373            } finally {
7374                Binder.restoreCallingIdentity(origId);
7375            }
7376            ActivityOptions.abort(options);
7377        }
7378    }
7379
7380    @Override
7381    public void moveTaskToBack(int taskId) {
7382        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7383                "moveTaskToBack()");
7384
7385        synchronized(this) {
7386            TaskRecord tr = recentTaskForIdLocked(taskId);
7387            if (tr != null) {
7388                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7389                ActivityStack stack = tr.stack;
7390                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7391                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7392                            Binder.getCallingUid(), "Task to back")) {
7393                        return;
7394                    }
7395                }
7396                final long origId = Binder.clearCallingIdentity();
7397                try {
7398                    stack.moveTaskToBackLocked(taskId, null);
7399                } finally {
7400                    Binder.restoreCallingIdentity(origId);
7401                }
7402            }
7403        }
7404    }
7405
7406    /**
7407     * Moves an activity, and all of the other activities within the same task, to the bottom
7408     * of the history stack.  The activity's order within the task is unchanged.
7409     *
7410     * @param token A reference to the activity we wish to move
7411     * @param nonRoot If false then this only works if the activity is the root
7412     *                of a task; if true it will work for any activity in a task.
7413     * @return Returns true if the move completed, false if not.
7414     */
7415    @Override
7416    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7417        enforceNotIsolatedCaller("moveActivityTaskToBack");
7418        synchronized(this) {
7419            final long origId = Binder.clearCallingIdentity();
7420            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7421            if (taskId >= 0) {
7422                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7423            }
7424            Binder.restoreCallingIdentity(origId);
7425        }
7426        return false;
7427    }
7428
7429    @Override
7430    public void moveTaskBackwards(int task) {
7431        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7432                "moveTaskBackwards()");
7433
7434        synchronized(this) {
7435            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7436                    Binder.getCallingUid(), "Task backwards")) {
7437                return;
7438            }
7439            final long origId = Binder.clearCallingIdentity();
7440            moveTaskBackwardsLocked(task);
7441            Binder.restoreCallingIdentity(origId);
7442        }
7443    }
7444
7445    private final void moveTaskBackwardsLocked(int task) {
7446        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7447    }
7448
7449    @Override
7450    public IBinder getHomeActivityToken() throws RemoteException {
7451        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7452                "getHomeActivityToken()");
7453        synchronized (this) {
7454            return mStackSupervisor.getHomeActivityToken();
7455        }
7456    }
7457
7458    @Override
7459    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7460            IActivityContainerCallback callback) throws RemoteException {
7461        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7462                "createActivityContainer()");
7463        synchronized (this) {
7464            if (parentActivityToken == null) {
7465                throw new IllegalArgumentException("parent token must not be null");
7466            }
7467            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7468            if (r == null) {
7469                return null;
7470            }
7471            if (callback == null) {
7472                throw new IllegalArgumentException("callback must not be null");
7473            }
7474            return mStackSupervisor.createActivityContainer(r, callback);
7475        }
7476    }
7477
7478    @Override
7479    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7480        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7481                "deleteActivityContainer()");
7482        synchronized (this) {
7483            mStackSupervisor.deleteActivityContainer(container);
7484        }
7485    }
7486
7487    @Override
7488    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7489            throws RemoteException {
7490        synchronized (this) {
7491            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7492            if (stack != null) {
7493                return stack.mActivityContainer;
7494            }
7495            return null;
7496        }
7497    }
7498
7499    @Override
7500    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7501        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7502                "moveTaskToStack()");
7503        if (stackId == HOME_STACK_ID) {
7504            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7505                    new RuntimeException("here").fillInStackTrace());
7506        }
7507        synchronized (this) {
7508            long ident = Binder.clearCallingIdentity();
7509            try {
7510                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7511                        + stackId + " toTop=" + toTop);
7512                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7513            } finally {
7514                Binder.restoreCallingIdentity(ident);
7515            }
7516        }
7517    }
7518
7519    @Override
7520    public void resizeStack(int stackBoxId, Rect bounds) {
7521        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7522                "resizeStackBox()");
7523        long ident = Binder.clearCallingIdentity();
7524        try {
7525            mWindowManager.resizeStack(stackBoxId, bounds);
7526        } finally {
7527            Binder.restoreCallingIdentity(ident);
7528        }
7529    }
7530
7531    @Override
7532    public List<StackInfo> getAllStackInfos() {
7533        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7534                "getAllStackInfos()");
7535        long ident = Binder.clearCallingIdentity();
7536        try {
7537            synchronized (this) {
7538                return mStackSupervisor.getAllStackInfosLocked();
7539            }
7540        } finally {
7541            Binder.restoreCallingIdentity(ident);
7542        }
7543    }
7544
7545    @Override
7546    public StackInfo getStackInfo(int stackId) {
7547        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7548                "getStackInfo()");
7549        long ident = Binder.clearCallingIdentity();
7550        try {
7551            synchronized (this) {
7552                return mStackSupervisor.getStackInfoLocked(stackId);
7553            }
7554        } finally {
7555            Binder.restoreCallingIdentity(ident);
7556        }
7557    }
7558
7559    @Override
7560    public boolean isInHomeStack(int taskId) {
7561        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7562                "getStackInfo()");
7563        long ident = Binder.clearCallingIdentity();
7564        try {
7565            synchronized (this) {
7566                TaskRecord tr = recentTaskForIdLocked(taskId);
7567                if (tr != null) {
7568                    return tr.stack.isHomeStack();
7569                }
7570            }
7571        } finally {
7572            Binder.restoreCallingIdentity(ident);
7573        }
7574        return false;
7575    }
7576
7577    @Override
7578    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7579        synchronized(this) {
7580            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7581        }
7582    }
7583
7584    private boolean isLockTaskAuthorized(ComponentName name) {
7585//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7586//                "startLockTaskMode()");
7587//        DevicePolicyManager dpm = (DevicePolicyManager)
7588//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7589//        return dpm != null && dpm.isLockTaskPermitted(name);
7590        return true;
7591    }
7592
7593    private void startLockTaskMode(TaskRecord task) {
7594        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7595            return;
7596        }
7597        long ident = Binder.clearCallingIdentity();
7598        try {
7599            synchronized (this) {
7600                // Since we lost lock on task, make sure it is still there.
7601                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7602                if (task != null) {
7603                    mStackSupervisor.setLockTaskModeLocked(task);
7604                }
7605            }
7606        } finally {
7607            Binder.restoreCallingIdentity(ident);
7608        }
7609    }
7610
7611    @Override
7612    public void startLockTaskMode(int taskId) {
7613        long ident = Binder.clearCallingIdentity();
7614        try {
7615            final TaskRecord task;
7616            synchronized (this) {
7617                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7618            }
7619            if (task != null) {
7620                startLockTaskMode(task);
7621            }
7622        } finally {
7623            Binder.restoreCallingIdentity(ident);
7624        }
7625    }
7626
7627    @Override
7628    public void startLockTaskMode(IBinder token) {
7629        long ident = Binder.clearCallingIdentity();
7630        try {
7631            final TaskRecord task;
7632            synchronized (this) {
7633                final ActivityRecord r = ActivityRecord.forToken(token);
7634                if (r == null) {
7635                    return;
7636                }
7637                task = r.task;
7638            }
7639            if (task != null) {
7640                startLockTaskMode(task);
7641            }
7642        } finally {
7643            Binder.restoreCallingIdentity(ident);
7644        }
7645    }
7646
7647    @Override
7648    public void stopLockTaskMode() {
7649//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7650//                "stopLockTaskMode()");
7651        synchronized (this) {
7652            mStackSupervisor.setLockTaskModeLocked(null);
7653        }
7654    }
7655
7656    @Override
7657    public boolean isInLockTaskMode() {
7658        synchronized (this) {
7659            return mStackSupervisor.isInLockTaskMode();
7660        }
7661    }
7662
7663    // =========================================================
7664    // CONTENT PROVIDERS
7665    // =========================================================
7666
7667    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7668        List<ProviderInfo> providers = null;
7669        try {
7670            providers = AppGlobals.getPackageManager().
7671                queryContentProviders(app.processName, app.uid,
7672                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7673        } catch (RemoteException ex) {
7674        }
7675        if (DEBUG_MU)
7676            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7677        int userId = app.userId;
7678        if (providers != null) {
7679            int N = providers.size();
7680            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7681            for (int i=0; i<N; i++) {
7682                ProviderInfo cpi =
7683                    (ProviderInfo)providers.get(i);
7684                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7685                        cpi.name, cpi.flags);
7686                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7687                    // This is a singleton provider, but a user besides the
7688                    // default user is asking to initialize a process it runs
7689                    // in...  well, no, it doesn't actually run in this process,
7690                    // it runs in the process of the default user.  Get rid of it.
7691                    providers.remove(i);
7692                    N--;
7693                    i--;
7694                    continue;
7695                }
7696
7697                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7698                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7699                if (cpr == null) {
7700                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7701                    mProviderMap.putProviderByClass(comp, cpr);
7702                }
7703                if (DEBUG_MU)
7704                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7705                app.pubProviders.put(cpi.name, cpr);
7706                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7707                    // Don't add this if it is a platform component that is marked
7708                    // to run in multiple processes, because this is actually
7709                    // part of the framework so doesn't make sense to track as a
7710                    // separate apk in the process.
7711                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7712                }
7713                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7714            }
7715        }
7716        return providers;
7717    }
7718
7719    /**
7720     * Check if {@link ProcessRecord} has a possible chance at accessing the
7721     * given {@link ProviderInfo}. Final permission checking is always done
7722     * in {@link ContentProvider}.
7723     */
7724    private final String checkContentProviderPermissionLocked(
7725            ProviderInfo cpi, ProcessRecord r, int userId) {
7726        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7727        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7728        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7729        // Looking for cross-user grants before to enforce the typical cross-users permissions
7730        if (userId != UserHandle.getUserId(callingUid)) {
7731            if (perms != null) {
7732                for (GrantUri grantUri : perms.keySet()) {
7733                    if (grantUri.sourceUserId == userId) {
7734                        String authority = grantUri.uri.getAuthority();
7735                        if (authority.equals(cpi.authority)) {
7736                            return null;
7737                        }
7738                    }
7739                }
7740            }
7741        }
7742        userId = handleIncomingUser(callingPid, callingUid, userId,
7743                false, true, "checkContentProviderPermissionLocked", null);
7744        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7745                cpi.applicationInfo.uid, cpi.exported)
7746                == PackageManager.PERMISSION_GRANTED) {
7747            return null;
7748        }
7749        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7750                cpi.applicationInfo.uid, cpi.exported)
7751                == PackageManager.PERMISSION_GRANTED) {
7752            return null;
7753        }
7754
7755        PathPermission[] pps = cpi.pathPermissions;
7756        if (pps != null) {
7757            int i = pps.length;
7758            while (i > 0) {
7759                i--;
7760                PathPermission pp = pps[i];
7761                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7762                        cpi.applicationInfo.uid, cpi.exported)
7763                        == PackageManager.PERMISSION_GRANTED) {
7764                    return null;
7765                }
7766                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7767                        cpi.applicationInfo.uid, cpi.exported)
7768                        == PackageManager.PERMISSION_GRANTED) {
7769                    return null;
7770                }
7771            }
7772        }
7773
7774        if (perms != null) {
7775            for (GrantUri grantUri : perms.keySet()) {
7776                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7777                    return null;
7778                }
7779            }
7780        }
7781
7782        String msg;
7783        if (!cpi.exported) {
7784            msg = "Permission Denial: opening provider " + cpi.name
7785                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7786                    + ", uid=" + callingUid + ") that is not exported from uid "
7787                    + cpi.applicationInfo.uid;
7788        } else {
7789            msg = "Permission Denial: opening provider " + cpi.name
7790                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7791                    + ", uid=" + callingUid + ") requires "
7792                    + cpi.readPermission + " or " + cpi.writePermission;
7793        }
7794        Slog.w(TAG, msg);
7795        return msg;
7796    }
7797
7798    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7799            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7800        if (r != null) {
7801            for (int i=0; i<r.conProviders.size(); i++) {
7802                ContentProviderConnection conn = r.conProviders.get(i);
7803                if (conn.provider == cpr) {
7804                    if (DEBUG_PROVIDER) Slog.v(TAG,
7805                            "Adding provider requested by "
7806                            + r.processName + " from process "
7807                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7808                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7809                    if (stable) {
7810                        conn.stableCount++;
7811                        conn.numStableIncs++;
7812                    } else {
7813                        conn.unstableCount++;
7814                        conn.numUnstableIncs++;
7815                    }
7816                    return conn;
7817                }
7818            }
7819            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7820            if (stable) {
7821                conn.stableCount = 1;
7822                conn.numStableIncs = 1;
7823            } else {
7824                conn.unstableCount = 1;
7825                conn.numUnstableIncs = 1;
7826            }
7827            cpr.connections.add(conn);
7828            r.conProviders.add(conn);
7829            return conn;
7830        }
7831        cpr.addExternalProcessHandleLocked(externalProcessToken);
7832        return null;
7833    }
7834
7835    boolean decProviderCountLocked(ContentProviderConnection conn,
7836            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7837        if (conn != null) {
7838            cpr = conn.provider;
7839            if (DEBUG_PROVIDER) Slog.v(TAG,
7840                    "Removing provider requested by "
7841                    + conn.client.processName + " from process "
7842                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7843                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7844            if (stable) {
7845                conn.stableCount--;
7846            } else {
7847                conn.unstableCount--;
7848            }
7849            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7850                cpr.connections.remove(conn);
7851                conn.client.conProviders.remove(conn);
7852                return true;
7853            }
7854            return false;
7855        }
7856        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7857        return false;
7858    }
7859
7860    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7861            String name, IBinder token, boolean stable, int userId) {
7862        ContentProviderRecord cpr;
7863        ContentProviderConnection conn = null;
7864        ProviderInfo cpi = null;
7865
7866        synchronized(this) {
7867            ProcessRecord r = null;
7868            if (caller != null) {
7869                r = getRecordForAppLocked(caller);
7870                if (r == null) {
7871                    throw new SecurityException(
7872                            "Unable to find app for caller " + caller
7873                          + " (pid=" + Binder.getCallingPid()
7874                          + ") when getting content provider " + name);
7875                }
7876            }
7877
7878            // First check if this content provider has been published...
7879            cpr = mProviderMap.getProviderByName(name, userId);
7880            boolean providerRunning = cpr != null;
7881            if (providerRunning) {
7882                cpi = cpr.info;
7883                String msg;
7884                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7885                    throw new SecurityException(msg);
7886                }
7887
7888                if (r != null && cpr.canRunHere(r)) {
7889                    // This provider has been published or is in the process
7890                    // of being published...  but it is also allowed to run
7891                    // in the caller's process, so don't make a connection
7892                    // and just let the caller instantiate its own instance.
7893                    ContentProviderHolder holder = cpr.newHolder(null);
7894                    // don't give caller the provider object, it needs
7895                    // to make its own.
7896                    holder.provider = null;
7897                    return holder;
7898                }
7899
7900                final long origId = Binder.clearCallingIdentity();
7901
7902                // In this case the provider instance already exists, so we can
7903                // return it right away.
7904                conn = incProviderCountLocked(r, cpr, token, stable);
7905                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7906                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7907                        // If this is a perceptible app accessing the provider,
7908                        // make sure to count it as being accessed and thus
7909                        // back up on the LRU list.  This is good because
7910                        // content providers are often expensive to start.
7911                        updateLruProcessLocked(cpr.proc, false, null);
7912                    }
7913                }
7914
7915                if (cpr.proc != null) {
7916                    if (false) {
7917                        if (cpr.name.flattenToShortString().equals(
7918                                "com.android.providers.calendar/.CalendarProvider2")) {
7919                            Slog.v(TAG, "****************** KILLING "
7920                                + cpr.name.flattenToShortString());
7921                            Process.killProcess(cpr.proc.pid);
7922                        }
7923                    }
7924                    boolean success = updateOomAdjLocked(cpr.proc);
7925                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7926                    // NOTE: there is still a race here where a signal could be
7927                    // pending on the process even though we managed to update its
7928                    // adj level.  Not sure what to do about this, but at least
7929                    // the race is now smaller.
7930                    if (!success) {
7931                        // Uh oh...  it looks like the provider's process
7932                        // has been killed on us.  We need to wait for a new
7933                        // process to be started, and make sure its death
7934                        // doesn't kill our process.
7935                        Slog.i(TAG,
7936                                "Existing provider " + cpr.name.flattenToShortString()
7937                                + " is crashing; detaching " + r);
7938                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7939                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7940                        if (!lastRef) {
7941                            // This wasn't the last ref our process had on
7942                            // the provider...  we have now been killed, bail.
7943                            return null;
7944                        }
7945                        providerRunning = false;
7946                        conn = null;
7947                    }
7948                }
7949
7950                Binder.restoreCallingIdentity(origId);
7951            }
7952
7953            boolean singleton;
7954            if (!providerRunning) {
7955                try {
7956                    cpi = AppGlobals.getPackageManager().
7957                        resolveContentProvider(name,
7958                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7959                } catch (RemoteException ex) {
7960                }
7961                if (cpi == null) {
7962                    return null;
7963                }
7964                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7965                        cpi.name, cpi.flags);
7966                if (singleton) {
7967                    userId = 0;
7968                }
7969                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7970
7971                String msg;
7972                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7973                    throw new SecurityException(msg);
7974                }
7975
7976                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7977                        && !cpi.processName.equals("system")) {
7978                    // If this content provider does not run in the system
7979                    // process, and the system is not yet ready to run other
7980                    // processes, then fail fast instead of hanging.
7981                    throw new IllegalArgumentException(
7982                            "Attempt to launch content provider before system ready");
7983                }
7984
7985                // Make sure that the user who owns this provider is started.  If not,
7986                // we don't want to allow it to run.
7987                if (mStartedUsers.get(userId) == null) {
7988                    Slog.w(TAG, "Unable to launch app "
7989                            + cpi.applicationInfo.packageName + "/"
7990                            + cpi.applicationInfo.uid + " for provider "
7991                            + name + ": user " + userId + " is stopped");
7992                    return null;
7993                }
7994
7995                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7996                cpr = mProviderMap.getProviderByClass(comp, userId);
7997                final boolean firstClass = cpr == null;
7998                if (firstClass) {
7999                    try {
8000                        ApplicationInfo ai =
8001                            AppGlobals.getPackageManager().
8002                                getApplicationInfo(
8003                                        cpi.applicationInfo.packageName,
8004                                        STOCK_PM_FLAGS, userId);
8005                        if (ai == null) {
8006                            Slog.w(TAG, "No package info for content provider "
8007                                    + cpi.name);
8008                            return null;
8009                        }
8010                        ai = getAppInfoForUser(ai, userId);
8011                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8012                    } catch (RemoteException ex) {
8013                        // pm is in same process, this will never happen.
8014                    }
8015                }
8016
8017                if (r != null && cpr.canRunHere(r)) {
8018                    // If this is a multiprocess provider, then just return its
8019                    // info and allow the caller to instantiate it.  Only do
8020                    // this if the provider is the same user as the caller's
8021                    // process, or can run as root (so can be in any process).
8022                    return cpr.newHolder(null);
8023                }
8024
8025                if (DEBUG_PROVIDER) {
8026                    RuntimeException e = new RuntimeException("here");
8027                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8028                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8029                }
8030
8031                // This is single process, and our app is now connecting to it.
8032                // See if we are already in the process of launching this
8033                // provider.
8034                final int N = mLaunchingProviders.size();
8035                int i;
8036                for (i=0; i<N; i++) {
8037                    if (mLaunchingProviders.get(i) == cpr) {
8038                        break;
8039                    }
8040                }
8041
8042                // If the provider is not already being launched, then get it
8043                // started.
8044                if (i >= N) {
8045                    final long origId = Binder.clearCallingIdentity();
8046
8047                    try {
8048                        // Content provider is now in use, its package can't be stopped.
8049                        try {
8050                            AppGlobals.getPackageManager().setPackageStoppedState(
8051                                    cpr.appInfo.packageName, false, userId);
8052                        } catch (RemoteException e) {
8053                        } catch (IllegalArgumentException e) {
8054                            Slog.w(TAG, "Failed trying to unstop package "
8055                                    + cpr.appInfo.packageName + ": " + e);
8056                        }
8057
8058                        // Use existing process if already started
8059                        ProcessRecord proc = getProcessRecordLocked(
8060                                cpi.processName, cpr.appInfo.uid, false);
8061                        if (proc != null && proc.thread != null) {
8062                            if (DEBUG_PROVIDER) {
8063                                Slog.d(TAG, "Installing in existing process " + proc);
8064                            }
8065                            proc.pubProviders.put(cpi.name, cpr);
8066                            try {
8067                                proc.thread.scheduleInstallProvider(cpi);
8068                            } catch (RemoteException e) {
8069                            }
8070                        } else {
8071                            proc = startProcessLocked(cpi.processName,
8072                                    cpr.appInfo, false, 0, "content provider",
8073                                    new ComponentName(cpi.applicationInfo.packageName,
8074                                            cpi.name), false, false, false);
8075                            if (proc == null) {
8076                                Slog.w(TAG, "Unable to launch app "
8077                                        + cpi.applicationInfo.packageName + "/"
8078                                        + cpi.applicationInfo.uid + " for provider "
8079                                        + name + ": process is bad");
8080                                return null;
8081                            }
8082                        }
8083                        cpr.launchingApp = proc;
8084                        mLaunchingProviders.add(cpr);
8085                    } finally {
8086                        Binder.restoreCallingIdentity(origId);
8087                    }
8088                }
8089
8090                // Make sure the provider is published (the same provider class
8091                // may be published under multiple names).
8092                if (firstClass) {
8093                    mProviderMap.putProviderByClass(comp, cpr);
8094                }
8095
8096                mProviderMap.putProviderByName(name, cpr);
8097                conn = incProviderCountLocked(r, cpr, token, stable);
8098                if (conn != null) {
8099                    conn.waiting = true;
8100                }
8101            }
8102        }
8103
8104        // Wait for the provider to be published...
8105        synchronized (cpr) {
8106            while (cpr.provider == null) {
8107                if (cpr.launchingApp == null) {
8108                    Slog.w(TAG, "Unable to launch app "
8109                            + cpi.applicationInfo.packageName + "/"
8110                            + cpi.applicationInfo.uid + " for provider "
8111                            + name + ": launching app became null");
8112                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8113                            UserHandle.getUserId(cpi.applicationInfo.uid),
8114                            cpi.applicationInfo.packageName,
8115                            cpi.applicationInfo.uid, name);
8116                    return null;
8117                }
8118                try {
8119                    if (DEBUG_MU) {
8120                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8121                                + cpr.launchingApp);
8122                    }
8123                    if (conn != null) {
8124                        conn.waiting = true;
8125                    }
8126                    cpr.wait();
8127                } catch (InterruptedException ex) {
8128                } finally {
8129                    if (conn != null) {
8130                        conn.waiting = false;
8131                    }
8132                }
8133            }
8134        }
8135        return cpr != null ? cpr.newHolder(conn) : null;
8136    }
8137
8138    @Override
8139    public final ContentProviderHolder getContentProvider(
8140            IApplicationThread caller, String name, int userId, boolean stable) {
8141        enforceNotIsolatedCaller("getContentProvider");
8142        if (caller == null) {
8143            String msg = "null IApplicationThread when getting content provider "
8144                    + name;
8145            Slog.w(TAG, msg);
8146            throw new SecurityException(msg);
8147        }
8148        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8149        // with cross-user grant.
8150        return getContentProviderImpl(caller, name, null, stable, userId);
8151    }
8152
8153    public ContentProviderHolder getContentProviderExternal(
8154            String name, int userId, IBinder token) {
8155        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8156            "Do not have permission in call getContentProviderExternal()");
8157        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8158                false, true, "getContentProvider", null);
8159        return getContentProviderExternalUnchecked(name, token, userId);
8160    }
8161
8162    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8163            IBinder token, int userId) {
8164        return getContentProviderImpl(null, name, token, true, userId);
8165    }
8166
8167    /**
8168     * Drop a content provider from a ProcessRecord's bookkeeping
8169     */
8170    public void removeContentProvider(IBinder connection, boolean stable) {
8171        enforceNotIsolatedCaller("removeContentProvider");
8172        long ident = Binder.clearCallingIdentity();
8173        try {
8174            synchronized (this) {
8175                ContentProviderConnection conn;
8176                try {
8177                    conn = (ContentProviderConnection)connection;
8178                } catch (ClassCastException e) {
8179                    String msg ="removeContentProvider: " + connection
8180                            + " not a ContentProviderConnection";
8181                    Slog.w(TAG, msg);
8182                    throw new IllegalArgumentException(msg);
8183                }
8184                if (conn == null) {
8185                    throw new NullPointerException("connection is null");
8186                }
8187                if (decProviderCountLocked(conn, null, null, stable)) {
8188                    updateOomAdjLocked();
8189                }
8190            }
8191        } finally {
8192            Binder.restoreCallingIdentity(ident);
8193        }
8194    }
8195
8196    public void removeContentProviderExternal(String name, IBinder token) {
8197        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8198            "Do not have permission in call removeContentProviderExternal()");
8199        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8200    }
8201
8202    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8203        synchronized (this) {
8204            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8205            if(cpr == null) {
8206                //remove from mProvidersByClass
8207                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8208                return;
8209            }
8210
8211            //update content provider record entry info
8212            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8213            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8214            if (localCpr.hasExternalProcessHandles()) {
8215                if (localCpr.removeExternalProcessHandleLocked(token)) {
8216                    updateOomAdjLocked();
8217                } else {
8218                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8219                            + " with no external reference for token: "
8220                            + token + ".");
8221                }
8222            } else {
8223                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8224                        + " with no external references.");
8225            }
8226        }
8227    }
8228
8229    public final void publishContentProviders(IApplicationThread caller,
8230            List<ContentProviderHolder> providers) {
8231        if (providers == null) {
8232            return;
8233        }
8234
8235        enforceNotIsolatedCaller("publishContentProviders");
8236        synchronized (this) {
8237            final ProcessRecord r = getRecordForAppLocked(caller);
8238            if (DEBUG_MU)
8239                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8240            if (r == null) {
8241                throw new SecurityException(
8242                        "Unable to find app for caller " + caller
8243                      + " (pid=" + Binder.getCallingPid()
8244                      + ") when publishing content providers");
8245            }
8246
8247            final long origId = Binder.clearCallingIdentity();
8248
8249            final int N = providers.size();
8250            for (int i=0; i<N; i++) {
8251                ContentProviderHolder src = providers.get(i);
8252                if (src == null || src.info == null || src.provider == null) {
8253                    continue;
8254                }
8255                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8256                if (DEBUG_MU)
8257                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8258                if (dst != null) {
8259                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8260                    mProviderMap.putProviderByClass(comp, dst);
8261                    String names[] = dst.info.authority.split(";");
8262                    for (int j = 0; j < names.length; j++) {
8263                        mProviderMap.putProviderByName(names[j], dst);
8264                    }
8265
8266                    int NL = mLaunchingProviders.size();
8267                    int j;
8268                    for (j=0; j<NL; j++) {
8269                        if (mLaunchingProviders.get(j) == dst) {
8270                            mLaunchingProviders.remove(j);
8271                            j--;
8272                            NL--;
8273                        }
8274                    }
8275                    synchronized (dst) {
8276                        dst.provider = src.provider;
8277                        dst.proc = r;
8278                        dst.notifyAll();
8279                    }
8280                    updateOomAdjLocked(r);
8281                }
8282            }
8283
8284            Binder.restoreCallingIdentity(origId);
8285        }
8286    }
8287
8288    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8289        ContentProviderConnection conn;
8290        try {
8291            conn = (ContentProviderConnection)connection;
8292        } catch (ClassCastException e) {
8293            String msg ="refContentProvider: " + connection
8294                    + " not a ContentProviderConnection";
8295            Slog.w(TAG, msg);
8296            throw new IllegalArgumentException(msg);
8297        }
8298        if (conn == null) {
8299            throw new NullPointerException("connection is null");
8300        }
8301
8302        synchronized (this) {
8303            if (stable > 0) {
8304                conn.numStableIncs += stable;
8305            }
8306            stable = conn.stableCount + stable;
8307            if (stable < 0) {
8308                throw new IllegalStateException("stableCount < 0: " + stable);
8309            }
8310
8311            if (unstable > 0) {
8312                conn.numUnstableIncs += unstable;
8313            }
8314            unstable = conn.unstableCount + unstable;
8315            if (unstable < 0) {
8316                throw new IllegalStateException("unstableCount < 0: " + unstable);
8317            }
8318
8319            if ((stable+unstable) <= 0) {
8320                throw new IllegalStateException("ref counts can't go to zero here: stable="
8321                        + stable + " unstable=" + unstable);
8322            }
8323            conn.stableCount = stable;
8324            conn.unstableCount = unstable;
8325            return !conn.dead;
8326        }
8327    }
8328
8329    public void unstableProviderDied(IBinder connection) {
8330        ContentProviderConnection conn;
8331        try {
8332            conn = (ContentProviderConnection)connection;
8333        } catch (ClassCastException e) {
8334            String msg ="refContentProvider: " + connection
8335                    + " not a ContentProviderConnection";
8336            Slog.w(TAG, msg);
8337            throw new IllegalArgumentException(msg);
8338        }
8339        if (conn == null) {
8340            throw new NullPointerException("connection is null");
8341        }
8342
8343        // Safely retrieve the content provider associated with the connection.
8344        IContentProvider provider;
8345        synchronized (this) {
8346            provider = conn.provider.provider;
8347        }
8348
8349        if (provider == null) {
8350            // Um, yeah, we're way ahead of you.
8351            return;
8352        }
8353
8354        // Make sure the caller is being honest with us.
8355        if (provider.asBinder().pingBinder()) {
8356            // Er, no, still looks good to us.
8357            synchronized (this) {
8358                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8359                        + " says " + conn + " died, but we don't agree");
8360                return;
8361            }
8362        }
8363
8364        // Well look at that!  It's dead!
8365        synchronized (this) {
8366            if (conn.provider.provider != provider) {
8367                // But something changed...  good enough.
8368                return;
8369            }
8370
8371            ProcessRecord proc = conn.provider.proc;
8372            if (proc == null || proc.thread == null) {
8373                // Seems like the process is already cleaned up.
8374                return;
8375            }
8376
8377            // As far as we're concerned, this is just like receiving a
8378            // death notification...  just a bit prematurely.
8379            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8380                    + ") early provider death");
8381            final long ident = Binder.clearCallingIdentity();
8382            try {
8383                appDiedLocked(proc, proc.pid, proc.thread);
8384            } finally {
8385                Binder.restoreCallingIdentity(ident);
8386            }
8387        }
8388    }
8389
8390    @Override
8391    public void appNotRespondingViaProvider(IBinder connection) {
8392        enforceCallingPermission(
8393                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8394
8395        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8396        if (conn == null) {
8397            Slog.w(TAG, "ContentProviderConnection is null");
8398            return;
8399        }
8400
8401        final ProcessRecord host = conn.provider.proc;
8402        if (host == null) {
8403            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8404            return;
8405        }
8406
8407        final long token = Binder.clearCallingIdentity();
8408        try {
8409            appNotResponding(host, null, null, false, "ContentProvider not responding");
8410        } finally {
8411            Binder.restoreCallingIdentity(token);
8412        }
8413    }
8414
8415    public final void installSystemProviders() {
8416        List<ProviderInfo> providers;
8417        synchronized (this) {
8418            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8419            providers = generateApplicationProvidersLocked(app);
8420            if (providers != null) {
8421                for (int i=providers.size()-1; i>=0; i--) {
8422                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8423                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8424                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8425                                + ": not system .apk");
8426                        providers.remove(i);
8427                    }
8428                }
8429            }
8430        }
8431        if (providers != null) {
8432            mSystemThread.installSystemProviders(providers);
8433        }
8434
8435        mCoreSettingsObserver = new CoreSettingsObserver(this);
8436
8437        mUsageStatsService.monitorPackages();
8438    }
8439
8440    /**
8441     * Allows app to retrieve the MIME type of a URI without having permission
8442     * to access its content provider.
8443     *
8444     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8445     *
8446     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8447     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8448     */
8449    public String getProviderMimeType(Uri uri, int userId) {
8450        enforceNotIsolatedCaller("getProviderMimeType");
8451        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8452                userId, false, true, "getProviderMimeType", null);
8453        final String name = uri.getAuthority();
8454        final long ident = Binder.clearCallingIdentity();
8455        ContentProviderHolder holder = null;
8456
8457        try {
8458            holder = getContentProviderExternalUnchecked(name, null, userId);
8459            if (holder != null) {
8460                return holder.provider.getType(uri);
8461            }
8462        } catch (RemoteException e) {
8463            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8464            return null;
8465        } finally {
8466            if (holder != null) {
8467                removeContentProviderExternalUnchecked(name, null, userId);
8468            }
8469            Binder.restoreCallingIdentity(ident);
8470        }
8471
8472        return null;
8473    }
8474
8475    // =========================================================
8476    // GLOBAL MANAGEMENT
8477    // =========================================================
8478
8479    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8480            boolean isolated) {
8481        String proc = customProcess != null ? customProcess : info.processName;
8482        BatteryStatsImpl.Uid.Proc ps = null;
8483        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8484        int uid = info.uid;
8485        if (isolated) {
8486            int userId = UserHandle.getUserId(uid);
8487            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8488            while (true) {
8489                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8490                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8491                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8492                }
8493                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8494                mNextIsolatedProcessUid++;
8495                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8496                    // No process for this uid, use it.
8497                    break;
8498                }
8499                stepsLeft--;
8500                if (stepsLeft <= 0) {
8501                    return null;
8502                }
8503            }
8504        }
8505        return new ProcessRecord(stats, info, proc, uid);
8506    }
8507
8508    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8509        ProcessRecord app;
8510        if (!isolated) {
8511            app = getProcessRecordLocked(info.processName, info.uid, true);
8512        } else {
8513            app = null;
8514        }
8515
8516        if (app == null) {
8517            app = newProcessRecordLocked(info, null, isolated);
8518            mProcessNames.put(info.processName, app.uid, app);
8519            if (isolated) {
8520                mIsolatedProcesses.put(app.uid, app);
8521            }
8522            updateLruProcessLocked(app, false, null);
8523            updateOomAdjLocked();
8524        }
8525
8526        // This package really, really can not be stopped.
8527        try {
8528            AppGlobals.getPackageManager().setPackageStoppedState(
8529                    info.packageName, false, UserHandle.getUserId(app.uid));
8530        } catch (RemoteException e) {
8531        } catch (IllegalArgumentException e) {
8532            Slog.w(TAG, "Failed trying to unstop package "
8533                    + info.packageName + ": " + e);
8534        }
8535
8536        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8537                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8538            app.persistent = true;
8539            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8540        }
8541        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8542            mPersistentStartingProcesses.add(app);
8543            startProcessLocked(app, "added application", app.processName);
8544        }
8545
8546        return app;
8547    }
8548
8549    public void unhandledBack() {
8550        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8551                "unhandledBack()");
8552
8553        synchronized(this) {
8554            final long origId = Binder.clearCallingIdentity();
8555            try {
8556                getFocusedStack().unhandledBackLocked();
8557            } finally {
8558                Binder.restoreCallingIdentity(origId);
8559            }
8560        }
8561    }
8562
8563    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8564        enforceNotIsolatedCaller("openContentUri");
8565        final int userId = UserHandle.getCallingUserId();
8566        String name = uri.getAuthority();
8567        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8568        ParcelFileDescriptor pfd = null;
8569        if (cph != null) {
8570            // We record the binder invoker's uid in thread-local storage before
8571            // going to the content provider to open the file.  Later, in the code
8572            // that handles all permissions checks, we look for this uid and use
8573            // that rather than the Activity Manager's own uid.  The effect is that
8574            // we do the check against the caller's permissions even though it looks
8575            // to the content provider like the Activity Manager itself is making
8576            // the request.
8577            sCallerIdentity.set(new Identity(
8578                    Binder.getCallingPid(), Binder.getCallingUid()));
8579            try {
8580                pfd = cph.provider.openFile(null, uri, "r", null);
8581            } catch (FileNotFoundException e) {
8582                // do nothing; pfd will be returned null
8583            } finally {
8584                // Ensure that whatever happens, we clean up the identity state
8585                sCallerIdentity.remove();
8586            }
8587
8588            // We've got the fd now, so we're done with the provider.
8589            removeContentProviderExternalUnchecked(name, null, userId);
8590        } else {
8591            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8592        }
8593        return pfd;
8594    }
8595
8596    // Actually is sleeping or shutting down or whatever else in the future
8597    // is an inactive state.
8598    public boolean isSleepingOrShuttingDown() {
8599        return mSleeping || mShuttingDown;
8600    }
8601
8602    public boolean isSleeping() {
8603        return mSleeping;
8604    }
8605
8606    void goingToSleep() {
8607        synchronized(this) {
8608            mWentToSleep = true;
8609            updateEventDispatchingLocked();
8610            goToSleepIfNeededLocked();
8611        }
8612    }
8613
8614    void finishRunningVoiceLocked() {
8615        if (mRunningVoice) {
8616            mRunningVoice = false;
8617            goToSleepIfNeededLocked();
8618        }
8619    }
8620
8621    void goToSleepIfNeededLocked() {
8622        if (mWentToSleep && !mRunningVoice) {
8623            if (!mSleeping) {
8624                mSleeping = true;
8625                mStackSupervisor.goingToSleepLocked();
8626
8627                // Initialize the wake times of all processes.
8628                checkExcessivePowerUsageLocked(false);
8629                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8630                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8631                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8632            }
8633        }
8634    }
8635
8636    @Override
8637    public boolean shutdown(int timeout) {
8638        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8639                != PackageManager.PERMISSION_GRANTED) {
8640            throw new SecurityException("Requires permission "
8641                    + android.Manifest.permission.SHUTDOWN);
8642        }
8643
8644        boolean timedout = false;
8645
8646        synchronized(this) {
8647            mShuttingDown = true;
8648            updateEventDispatchingLocked();
8649            timedout = mStackSupervisor.shutdownLocked(timeout);
8650        }
8651
8652        mAppOpsService.shutdown();
8653        mUsageStatsService.shutdown();
8654        mBatteryStatsService.shutdown();
8655        synchronized (this) {
8656            mProcessStats.shutdownLocked();
8657        }
8658
8659        return timedout;
8660    }
8661
8662    public final void activitySlept(IBinder token) {
8663        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8664
8665        final long origId = Binder.clearCallingIdentity();
8666
8667        synchronized (this) {
8668            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8669            if (r != null) {
8670                mStackSupervisor.activitySleptLocked(r);
8671            }
8672        }
8673
8674        Binder.restoreCallingIdentity(origId);
8675    }
8676
8677    void logLockScreen(String msg) {
8678        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8679                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8680                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8681                mStackSupervisor.mDismissKeyguardOnNextActivity);
8682    }
8683
8684    private void comeOutOfSleepIfNeededLocked() {
8685        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8686            if (mSleeping) {
8687                mSleeping = false;
8688                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8689            }
8690        }
8691    }
8692
8693    void wakingUp() {
8694        synchronized(this) {
8695            mWentToSleep = false;
8696            updateEventDispatchingLocked();
8697            comeOutOfSleepIfNeededLocked();
8698        }
8699    }
8700
8701    void startRunningVoiceLocked() {
8702        if (!mRunningVoice) {
8703            mRunningVoice = true;
8704            comeOutOfSleepIfNeededLocked();
8705        }
8706    }
8707
8708    private void updateEventDispatchingLocked() {
8709        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8710    }
8711
8712    public void setLockScreenShown(boolean shown) {
8713        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8714                != PackageManager.PERMISSION_GRANTED) {
8715            throw new SecurityException("Requires permission "
8716                    + android.Manifest.permission.DEVICE_POWER);
8717        }
8718
8719        synchronized(this) {
8720            long ident = Binder.clearCallingIdentity();
8721            try {
8722                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8723                mLockScreenShown = shown;
8724                comeOutOfSleepIfNeededLocked();
8725            } finally {
8726                Binder.restoreCallingIdentity(ident);
8727            }
8728        }
8729    }
8730
8731    public void stopAppSwitches() {
8732        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8733                != PackageManager.PERMISSION_GRANTED) {
8734            throw new SecurityException("Requires permission "
8735                    + android.Manifest.permission.STOP_APP_SWITCHES);
8736        }
8737
8738        synchronized(this) {
8739            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8740                    + APP_SWITCH_DELAY_TIME;
8741            mDidAppSwitch = false;
8742            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8743            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8744            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8745        }
8746    }
8747
8748    public void resumeAppSwitches() {
8749        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8750                != PackageManager.PERMISSION_GRANTED) {
8751            throw new SecurityException("Requires permission "
8752                    + android.Manifest.permission.STOP_APP_SWITCHES);
8753        }
8754
8755        synchronized(this) {
8756            // Note that we don't execute any pending app switches... we will
8757            // let those wait until either the timeout, or the next start
8758            // activity request.
8759            mAppSwitchesAllowedTime = 0;
8760        }
8761    }
8762
8763    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8764            String name) {
8765        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8766            return true;
8767        }
8768
8769        final int perm = checkComponentPermission(
8770                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8771                callingUid, -1, true);
8772        if (perm == PackageManager.PERMISSION_GRANTED) {
8773            return true;
8774        }
8775
8776        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8777        return false;
8778    }
8779
8780    public void setDebugApp(String packageName, boolean waitForDebugger,
8781            boolean persistent) {
8782        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8783                "setDebugApp()");
8784
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            // Note that this is not really thread safe if there are multiple
8788            // callers into it at the same time, but that's not a situation we
8789            // care about.
8790            if (persistent) {
8791                final ContentResolver resolver = mContext.getContentResolver();
8792                Settings.Global.putString(
8793                    resolver, Settings.Global.DEBUG_APP,
8794                    packageName);
8795                Settings.Global.putInt(
8796                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8797                    waitForDebugger ? 1 : 0);
8798            }
8799
8800            synchronized (this) {
8801                if (!persistent) {
8802                    mOrigDebugApp = mDebugApp;
8803                    mOrigWaitForDebugger = mWaitForDebugger;
8804                }
8805                mDebugApp = packageName;
8806                mWaitForDebugger = waitForDebugger;
8807                mDebugTransient = !persistent;
8808                if (packageName != null) {
8809                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8810                            false, UserHandle.USER_ALL, "set debug app");
8811                }
8812            }
8813        } finally {
8814            Binder.restoreCallingIdentity(ident);
8815        }
8816    }
8817
8818    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8819        synchronized (this) {
8820            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8821            if (!isDebuggable) {
8822                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8823                    throw new SecurityException("Process not debuggable: " + app.packageName);
8824                }
8825            }
8826
8827            mOpenGlTraceApp = processName;
8828        }
8829    }
8830
8831    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8832            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8833        synchronized (this) {
8834            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8835            if (!isDebuggable) {
8836                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8837                    throw new SecurityException("Process not debuggable: " + app.packageName);
8838                }
8839            }
8840            mProfileApp = processName;
8841            mProfileFile = profileFile;
8842            if (mProfileFd != null) {
8843                try {
8844                    mProfileFd.close();
8845                } catch (IOException e) {
8846                }
8847                mProfileFd = null;
8848            }
8849            mProfileFd = profileFd;
8850            mProfileType = 0;
8851            mAutoStopProfiler = autoStopProfiler;
8852        }
8853    }
8854
8855    @Override
8856    public void setAlwaysFinish(boolean enabled) {
8857        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8858                "setAlwaysFinish()");
8859
8860        Settings.Global.putInt(
8861                mContext.getContentResolver(),
8862                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8863
8864        synchronized (this) {
8865            mAlwaysFinishActivities = enabled;
8866        }
8867    }
8868
8869    @Override
8870    public void setActivityController(IActivityController controller) {
8871        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8872                "setActivityController()");
8873        synchronized (this) {
8874            mController = controller;
8875            Watchdog.getInstance().setActivityController(controller);
8876        }
8877    }
8878
8879    @Override
8880    public void setUserIsMonkey(boolean userIsMonkey) {
8881        synchronized (this) {
8882            synchronized (mPidsSelfLocked) {
8883                final int callingPid = Binder.getCallingPid();
8884                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8885                if (precessRecord == null) {
8886                    throw new SecurityException("Unknown process: " + callingPid);
8887                }
8888                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8889                    throw new SecurityException("Only an instrumentation process "
8890                            + "with a UiAutomation can call setUserIsMonkey");
8891                }
8892            }
8893            mUserIsMonkey = userIsMonkey;
8894        }
8895    }
8896
8897    @Override
8898    public boolean isUserAMonkey() {
8899        synchronized (this) {
8900            // If there is a controller also implies the user is a monkey.
8901            return (mUserIsMonkey || mController != null);
8902        }
8903    }
8904
8905    public void requestBugReport() {
8906        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8907        SystemProperties.set("ctl.start", "bugreport");
8908    }
8909
8910    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8911        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8912    }
8913
8914    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8915        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8916            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8917        }
8918        return KEY_DISPATCHING_TIMEOUT;
8919    }
8920
8921    @Override
8922    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8923        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8924                != PackageManager.PERMISSION_GRANTED) {
8925            throw new SecurityException("Requires permission "
8926                    + android.Manifest.permission.FILTER_EVENTS);
8927        }
8928        ProcessRecord proc;
8929        long timeout;
8930        synchronized (this) {
8931            synchronized (mPidsSelfLocked) {
8932                proc = mPidsSelfLocked.get(pid);
8933            }
8934            timeout = getInputDispatchingTimeoutLocked(proc);
8935        }
8936
8937        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8938            return -1;
8939        }
8940
8941        return timeout;
8942    }
8943
8944    /**
8945     * Handle input dispatching timeouts.
8946     * Returns whether input dispatching should be aborted or not.
8947     */
8948    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8949            final ActivityRecord activity, final ActivityRecord parent,
8950            final boolean aboveSystem, String reason) {
8951        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8952                != PackageManager.PERMISSION_GRANTED) {
8953            throw new SecurityException("Requires permission "
8954                    + android.Manifest.permission.FILTER_EVENTS);
8955        }
8956
8957        final String annotation;
8958        if (reason == null) {
8959            annotation = "Input dispatching timed out";
8960        } else {
8961            annotation = "Input dispatching timed out (" + reason + ")";
8962        }
8963
8964        if (proc != null) {
8965            synchronized (this) {
8966                if (proc.debugging) {
8967                    return false;
8968                }
8969
8970                if (mDidDexOpt) {
8971                    // Give more time since we were dexopting.
8972                    mDidDexOpt = false;
8973                    return false;
8974                }
8975
8976                if (proc.instrumentationClass != null) {
8977                    Bundle info = new Bundle();
8978                    info.putString("shortMsg", "keyDispatchingTimedOut");
8979                    info.putString("longMsg", annotation);
8980                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8981                    return true;
8982                }
8983            }
8984            mHandler.post(new Runnable() {
8985                @Override
8986                public void run() {
8987                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8988                }
8989            });
8990        }
8991
8992        return true;
8993    }
8994
8995    public Bundle getAssistContextExtras(int requestType) {
8996        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8997                "getAssistContextExtras()");
8998        PendingAssistExtras pae;
8999        Bundle extras = new Bundle();
9000        synchronized (this) {
9001            ActivityRecord activity = getFocusedStack().mResumedActivity;
9002            if (activity == null) {
9003                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9004                return null;
9005            }
9006            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9007            if (activity.app == null || activity.app.thread == null) {
9008                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9009                return extras;
9010            }
9011            if (activity.app.pid == Binder.getCallingPid()) {
9012                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9013                return extras;
9014            }
9015            pae = new PendingAssistExtras(activity);
9016            try {
9017                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9018                        requestType);
9019                mPendingAssistExtras.add(pae);
9020                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9021            } catch (RemoteException e) {
9022                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9023                return extras;
9024            }
9025        }
9026        synchronized (pae) {
9027            while (!pae.haveResult) {
9028                try {
9029                    pae.wait();
9030                } catch (InterruptedException e) {
9031                }
9032            }
9033            if (pae.result != null) {
9034                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9035            }
9036        }
9037        synchronized (this) {
9038            mPendingAssistExtras.remove(pae);
9039            mHandler.removeCallbacks(pae);
9040        }
9041        return extras;
9042    }
9043
9044    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9045        PendingAssistExtras pae = (PendingAssistExtras)token;
9046        synchronized (pae) {
9047            pae.result = extras;
9048            pae.haveResult = true;
9049            pae.notifyAll();
9050        }
9051    }
9052
9053    public void registerProcessObserver(IProcessObserver observer) {
9054        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9055                "registerProcessObserver()");
9056        synchronized (this) {
9057            mProcessObservers.register(observer);
9058        }
9059    }
9060
9061    @Override
9062    public void unregisterProcessObserver(IProcessObserver observer) {
9063        synchronized (this) {
9064            mProcessObservers.unregister(observer);
9065        }
9066    }
9067
9068    @Override
9069    public boolean convertFromTranslucent(IBinder token) {
9070        final long origId = Binder.clearCallingIdentity();
9071        try {
9072            synchronized (this) {
9073                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9074                if (r == null) {
9075                    return false;
9076                }
9077                if (r.changeWindowTranslucency(true)) {
9078                    mWindowManager.setAppFullscreen(token, true);
9079                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9080                    return true;
9081                }
9082                return false;
9083            }
9084        } finally {
9085            Binder.restoreCallingIdentity(origId);
9086        }
9087    }
9088
9089    @Override
9090    public boolean convertToTranslucent(IBinder token) {
9091        final long origId = Binder.clearCallingIdentity();
9092        try {
9093            synchronized (this) {
9094                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9095                if (r == null) {
9096                    return false;
9097                }
9098                if (r.changeWindowTranslucency(false)) {
9099                    r.task.stack.convertToTranslucent(r);
9100                    mWindowManager.setAppFullscreen(token, false);
9101                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9102                    return true;
9103                }
9104                return false;
9105            }
9106        } finally {
9107            Binder.restoreCallingIdentity(origId);
9108        }
9109    }
9110
9111    @Override
9112    public void setImmersive(IBinder token, boolean immersive) {
9113        synchronized(this) {
9114            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9115            if (r == null) {
9116                throw new IllegalArgumentException();
9117            }
9118            r.immersive = immersive;
9119
9120            // update associated state if we're frontmost
9121            if (r == mFocusedActivity) {
9122                if (DEBUG_IMMERSIVE) {
9123                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9124                }
9125                applyUpdateLockStateLocked(r);
9126            }
9127        }
9128    }
9129
9130    @Override
9131    public boolean isImmersive(IBinder token) {
9132        synchronized (this) {
9133            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9134            if (r == null) {
9135                throw new IllegalArgumentException();
9136            }
9137            return r.immersive;
9138        }
9139    }
9140
9141    public boolean isTopActivityImmersive() {
9142        enforceNotIsolatedCaller("startActivity");
9143        synchronized (this) {
9144            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9145            return (r != null) ? r.immersive : false;
9146        }
9147    }
9148
9149    public final void enterSafeMode() {
9150        synchronized(this) {
9151            // It only makes sense to do this before the system is ready
9152            // and started launching other packages.
9153            if (!mSystemReady) {
9154                try {
9155                    AppGlobals.getPackageManager().enterSafeMode();
9156                } catch (RemoteException e) {
9157                }
9158            }
9159
9160            mSafeMode = true;
9161        }
9162    }
9163
9164    public final void showSafeModeOverlay() {
9165        View v = LayoutInflater.from(mContext).inflate(
9166                com.android.internal.R.layout.safe_mode, null);
9167        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9168        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9169        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9170        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9171        lp.gravity = Gravity.BOTTOM | Gravity.START;
9172        lp.format = v.getBackground().getOpacity();
9173        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9174                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9175        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9176        ((WindowManager)mContext.getSystemService(
9177                Context.WINDOW_SERVICE)).addView(v, lp);
9178    }
9179
9180    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9181        if (!(sender instanceof PendingIntentRecord)) {
9182            return;
9183        }
9184        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9185        synchronized (stats) {
9186            if (mBatteryStatsService.isOnBattery()) {
9187                mBatteryStatsService.enforceCallingPermission();
9188                PendingIntentRecord rec = (PendingIntentRecord)sender;
9189                int MY_UID = Binder.getCallingUid();
9190                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9191                BatteryStatsImpl.Uid.Pkg pkg =
9192                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9193                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9194                pkg.incWakeupsLocked();
9195            }
9196        }
9197    }
9198
9199    public boolean killPids(int[] pids, String pReason, boolean secure) {
9200        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9201            throw new SecurityException("killPids only available to the system");
9202        }
9203        String reason = (pReason == null) ? "Unknown" : pReason;
9204        // XXX Note: don't acquire main activity lock here, because the window
9205        // manager calls in with its locks held.
9206
9207        boolean killed = false;
9208        synchronized (mPidsSelfLocked) {
9209            int[] types = new int[pids.length];
9210            int worstType = 0;
9211            for (int i=0; i<pids.length; i++) {
9212                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9213                if (proc != null) {
9214                    int type = proc.setAdj;
9215                    types[i] = type;
9216                    if (type > worstType) {
9217                        worstType = type;
9218                    }
9219                }
9220            }
9221
9222            // If the worst oom_adj is somewhere in the cached proc LRU range,
9223            // then constrain it so we will kill all cached procs.
9224            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9225                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9226                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9227            }
9228
9229            // If this is not a secure call, don't let it kill processes that
9230            // are important.
9231            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9232                worstType = ProcessList.SERVICE_ADJ;
9233            }
9234
9235            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9236            for (int i=0; i<pids.length; i++) {
9237                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9238                if (proc == null) {
9239                    continue;
9240                }
9241                int adj = proc.setAdj;
9242                if (adj >= worstType && !proc.killedByAm) {
9243                    killUnneededProcessLocked(proc, reason);
9244                    killed = true;
9245                }
9246            }
9247        }
9248        return killed;
9249    }
9250
9251    @Override
9252    public void killUid(int uid, String reason) {
9253        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9254            throw new SecurityException("killUid only available to the system");
9255        }
9256        synchronized (this) {
9257            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9258                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9259                    reason != null ? reason : "kill uid");
9260        }
9261    }
9262
9263    @Override
9264    public boolean killProcessesBelowForeground(String reason) {
9265        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9266            throw new SecurityException("killProcessesBelowForeground() only available to system");
9267        }
9268
9269        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9270    }
9271
9272    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9273        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9274            throw new SecurityException("killProcessesBelowAdj() only available to system");
9275        }
9276
9277        boolean killed = false;
9278        synchronized (mPidsSelfLocked) {
9279            final int size = mPidsSelfLocked.size();
9280            for (int i = 0; i < size; i++) {
9281                final int pid = mPidsSelfLocked.keyAt(i);
9282                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9283                if (proc == null) continue;
9284
9285                final int adj = proc.setAdj;
9286                if (adj > belowAdj && !proc.killedByAm) {
9287                    killUnneededProcessLocked(proc, reason);
9288                    killed = true;
9289                }
9290            }
9291        }
9292        return killed;
9293    }
9294
9295    @Override
9296    public void hang(final IBinder who, boolean allowRestart) {
9297        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9298                != PackageManager.PERMISSION_GRANTED) {
9299            throw new SecurityException("Requires permission "
9300                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9301        }
9302
9303        final IBinder.DeathRecipient death = new DeathRecipient() {
9304            @Override
9305            public void binderDied() {
9306                synchronized (this) {
9307                    notifyAll();
9308                }
9309            }
9310        };
9311
9312        try {
9313            who.linkToDeath(death, 0);
9314        } catch (RemoteException e) {
9315            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9316            return;
9317        }
9318
9319        synchronized (this) {
9320            Watchdog.getInstance().setAllowRestart(allowRestart);
9321            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9322            synchronized (death) {
9323                while (who.isBinderAlive()) {
9324                    try {
9325                        death.wait();
9326                    } catch (InterruptedException e) {
9327                    }
9328                }
9329            }
9330            Watchdog.getInstance().setAllowRestart(true);
9331        }
9332    }
9333
9334    @Override
9335    public void restart() {
9336        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9337                != PackageManager.PERMISSION_GRANTED) {
9338            throw new SecurityException("Requires permission "
9339                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9340        }
9341
9342        Log.i(TAG, "Sending shutdown broadcast...");
9343
9344        BroadcastReceiver br = new BroadcastReceiver() {
9345            @Override public void onReceive(Context context, Intent intent) {
9346                // Now the broadcast is done, finish up the low-level shutdown.
9347                Log.i(TAG, "Shutting down activity manager...");
9348                shutdown(10000);
9349                Log.i(TAG, "Shutdown complete, restarting!");
9350                Process.killProcess(Process.myPid());
9351                System.exit(10);
9352            }
9353        };
9354
9355        // First send the high-level shut down broadcast.
9356        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9357        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9358        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9359        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9360        mContext.sendOrderedBroadcastAsUser(intent,
9361                UserHandle.ALL, null, br, mHandler, 0, null, null);
9362        */
9363        br.onReceive(mContext, intent);
9364    }
9365
9366    private long getLowRamTimeSinceIdle(long now) {
9367        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9368    }
9369
9370    @Override
9371    public void performIdleMaintenance() {
9372        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9373                != PackageManager.PERMISSION_GRANTED) {
9374            throw new SecurityException("Requires permission "
9375                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9376        }
9377
9378        synchronized (this) {
9379            final long now = SystemClock.uptimeMillis();
9380            final long timeSinceLastIdle = now - mLastIdleTime;
9381            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9382            mLastIdleTime = now;
9383            mLowRamTimeSinceLastIdle = 0;
9384            if (mLowRamStartTime != 0) {
9385                mLowRamStartTime = now;
9386            }
9387
9388            StringBuilder sb = new StringBuilder(128);
9389            sb.append("Idle maintenance over ");
9390            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9391            sb.append(" low RAM for ");
9392            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9393            Slog.i(TAG, sb.toString());
9394
9395            // If at least 1/3 of our time since the last idle period has been spent
9396            // with RAM low, then we want to kill processes.
9397            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9398
9399            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9400                ProcessRecord proc = mLruProcesses.get(i);
9401                if (proc.notCachedSinceIdle) {
9402                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9403                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9404                        if (doKilling && proc.initialIdlePss != 0
9405                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9406                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9407                                    + " from " + proc.initialIdlePss + ")");
9408                        }
9409                    }
9410                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9411                    proc.notCachedSinceIdle = true;
9412                    proc.initialIdlePss = 0;
9413                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9414                            isSleeping(), now);
9415                }
9416            }
9417
9418            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9419            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9420        }
9421    }
9422
9423    private void retrieveSettings() {
9424        final ContentResolver resolver = mContext.getContentResolver();
9425        String debugApp = Settings.Global.getString(
9426            resolver, Settings.Global.DEBUG_APP);
9427        boolean waitForDebugger = Settings.Global.getInt(
9428            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9429        boolean alwaysFinishActivities = Settings.Global.getInt(
9430            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9431        boolean forceRtl = Settings.Global.getInt(
9432                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9433        // Transfer any global setting for forcing RTL layout, into a System Property
9434        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9435
9436        Configuration configuration = new Configuration();
9437        Settings.System.getConfiguration(resolver, configuration);
9438        if (forceRtl) {
9439            // This will take care of setting the correct layout direction flags
9440            configuration.setLayoutDirection(configuration.locale);
9441        }
9442
9443        synchronized (this) {
9444            mDebugApp = mOrigDebugApp = debugApp;
9445            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9446            mAlwaysFinishActivities = alwaysFinishActivities;
9447            // This happens before any activities are started, so we can
9448            // change mConfiguration in-place.
9449            updateConfigurationLocked(configuration, null, false, true);
9450            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9451        }
9452    }
9453
9454    public boolean testIsSystemReady() {
9455        // no need to synchronize(this) just to read & return the value
9456        return mSystemReady;
9457    }
9458
9459    private static File getCalledPreBootReceiversFile() {
9460        File dataDir = Environment.getDataDirectory();
9461        File systemDir = new File(dataDir, "system");
9462        File fname = new File(systemDir, "called_pre_boots.dat");
9463        return fname;
9464    }
9465
9466    static final int LAST_DONE_VERSION = 10000;
9467
9468    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9469        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9470        File file = getCalledPreBootReceiversFile();
9471        FileInputStream fis = null;
9472        try {
9473            fis = new FileInputStream(file);
9474            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9475            int fvers = dis.readInt();
9476            if (fvers == LAST_DONE_VERSION) {
9477                String vers = dis.readUTF();
9478                String codename = dis.readUTF();
9479                String build = dis.readUTF();
9480                if (android.os.Build.VERSION.RELEASE.equals(vers)
9481                        && android.os.Build.VERSION.CODENAME.equals(codename)
9482                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9483                    int num = dis.readInt();
9484                    while (num > 0) {
9485                        num--;
9486                        String pkg = dis.readUTF();
9487                        String cls = dis.readUTF();
9488                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9489                    }
9490                }
9491            }
9492        } catch (FileNotFoundException e) {
9493        } catch (IOException e) {
9494            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9495        } finally {
9496            if (fis != null) {
9497                try {
9498                    fis.close();
9499                } catch (IOException e) {
9500                }
9501            }
9502        }
9503        return lastDoneReceivers;
9504    }
9505
9506    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9507        File file = getCalledPreBootReceiversFile();
9508        FileOutputStream fos = null;
9509        DataOutputStream dos = null;
9510        try {
9511            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9512            fos = new FileOutputStream(file);
9513            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9514            dos.writeInt(LAST_DONE_VERSION);
9515            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9516            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9517            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9518            dos.writeInt(list.size());
9519            for (int i=0; i<list.size(); i++) {
9520                dos.writeUTF(list.get(i).getPackageName());
9521                dos.writeUTF(list.get(i).getClassName());
9522            }
9523        } catch (IOException e) {
9524            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9525            file.delete();
9526        } finally {
9527            FileUtils.sync(fos);
9528            if (dos != null) {
9529                try {
9530                    dos.close();
9531                } catch (IOException e) {
9532                    // TODO Auto-generated catch block
9533                    e.printStackTrace();
9534                }
9535            }
9536        }
9537    }
9538
9539    public void systemReady(final Runnable goingCallback) {
9540        synchronized(this) {
9541            if (mSystemReady) {
9542                if (goingCallback != null) goingCallback.run();
9543                return;
9544            }
9545
9546            // Check to see if there are any update receivers to run.
9547            if (!mDidUpdate) {
9548                if (mWaitingUpdate) {
9549                    return;
9550                }
9551                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9552                List<ResolveInfo> ris = null;
9553                try {
9554                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9555                            intent, null, 0, 0);
9556                } catch (RemoteException e) {
9557                }
9558                if (ris != null) {
9559                    for (int i=ris.size()-1; i>=0; i--) {
9560                        if ((ris.get(i).activityInfo.applicationInfo.flags
9561                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9562                            ris.remove(i);
9563                        }
9564                    }
9565                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9566
9567                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9568
9569                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9570                    for (int i=0; i<ris.size(); i++) {
9571                        ActivityInfo ai = ris.get(i).activityInfo;
9572                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9573                        if (lastDoneReceivers.contains(comp)) {
9574                            // We already did the pre boot receiver for this app with the current
9575                            // platform version, so don't do it again...
9576                            ris.remove(i);
9577                            i--;
9578                            // ...however, do keep it as one that has been done, so we don't
9579                            // forget about it when rewriting the file of last done receivers.
9580                            doneReceivers.add(comp);
9581                        }
9582                    }
9583
9584                    final int[] users = getUsersLocked();
9585                    for (int i=0; i<ris.size(); i++) {
9586                        ActivityInfo ai = ris.get(i).activityInfo;
9587                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9588                        doneReceivers.add(comp);
9589                        intent.setComponent(comp);
9590                        for (int j=0; j<users.length; j++) {
9591                            IIntentReceiver finisher = null;
9592                            if (i == ris.size()-1 && j == users.length-1) {
9593                                finisher = new IIntentReceiver.Stub() {
9594                                    public void performReceive(Intent intent, int resultCode,
9595                                            String data, Bundle extras, boolean ordered,
9596                                            boolean sticky, int sendingUser) {
9597                                        // The raw IIntentReceiver interface is called
9598                                        // with the AM lock held, so redispatch to
9599                                        // execute our code without the lock.
9600                                        mHandler.post(new Runnable() {
9601                                            public void run() {
9602                                                synchronized (ActivityManagerService.this) {
9603                                                    mDidUpdate = true;
9604                                                }
9605                                                writeLastDonePreBootReceivers(doneReceivers);
9606                                                showBootMessage(mContext.getText(
9607                                                        R.string.android_upgrading_complete),
9608                                                        false);
9609                                                systemReady(goingCallback);
9610                                            }
9611                                        });
9612                                    }
9613                                };
9614                            }
9615                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9616                                    + " for user " + users[j]);
9617                            broadcastIntentLocked(null, null, intent, null, finisher,
9618                                    0, null, null, null, AppOpsManager.OP_NONE,
9619                                    true, false, MY_PID, Process.SYSTEM_UID,
9620                                    users[j]);
9621                            if (finisher != null) {
9622                                mWaitingUpdate = true;
9623                            }
9624                        }
9625                    }
9626                }
9627                if (mWaitingUpdate) {
9628                    return;
9629                }
9630                mDidUpdate = true;
9631            }
9632
9633            mAppOpsService.systemReady();
9634            mUsageStatsService.systemReady();
9635            mSystemReady = true;
9636        }
9637
9638        ArrayList<ProcessRecord> procsToKill = null;
9639        synchronized(mPidsSelfLocked) {
9640            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9641                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9642                if (!isAllowedWhileBooting(proc.info)){
9643                    if (procsToKill == null) {
9644                        procsToKill = new ArrayList<ProcessRecord>();
9645                    }
9646                    procsToKill.add(proc);
9647                }
9648            }
9649        }
9650
9651        synchronized(this) {
9652            if (procsToKill != null) {
9653                for (int i=procsToKill.size()-1; i>=0; i--) {
9654                    ProcessRecord proc = procsToKill.get(i);
9655                    Slog.i(TAG, "Removing system update proc: " + proc);
9656                    removeProcessLocked(proc, true, false, "system update done");
9657                }
9658            }
9659
9660            // Now that we have cleaned up any update processes, we
9661            // are ready to start launching real processes and know that
9662            // we won't trample on them any more.
9663            mProcessesReady = true;
9664        }
9665
9666        Slog.i(TAG, "System now ready");
9667        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9668            SystemClock.uptimeMillis());
9669
9670        synchronized(this) {
9671            // Make sure we have no pre-ready processes sitting around.
9672
9673            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9674                ResolveInfo ri = mContext.getPackageManager()
9675                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9676                                STOCK_PM_FLAGS);
9677                CharSequence errorMsg = null;
9678                if (ri != null) {
9679                    ActivityInfo ai = ri.activityInfo;
9680                    ApplicationInfo app = ai.applicationInfo;
9681                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9682                        mTopAction = Intent.ACTION_FACTORY_TEST;
9683                        mTopData = null;
9684                        mTopComponent = new ComponentName(app.packageName,
9685                                ai.name);
9686                    } else {
9687                        errorMsg = mContext.getResources().getText(
9688                                com.android.internal.R.string.factorytest_not_system);
9689                    }
9690                } else {
9691                    errorMsg = mContext.getResources().getText(
9692                            com.android.internal.R.string.factorytest_no_action);
9693                }
9694                if (errorMsg != null) {
9695                    mTopAction = null;
9696                    mTopData = null;
9697                    mTopComponent = null;
9698                    Message msg = Message.obtain();
9699                    msg.what = SHOW_FACTORY_ERROR_MSG;
9700                    msg.getData().putCharSequence("msg", errorMsg);
9701                    mHandler.sendMessage(msg);
9702                }
9703            }
9704        }
9705
9706        retrieveSettings();
9707
9708        synchronized (this) {
9709            readGrantedUriPermissionsLocked();
9710        }
9711
9712        if (goingCallback != null) goingCallback.run();
9713
9714        mSystemServiceManager.startUser(mCurrentUserId);
9715
9716        synchronized (this) {
9717            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9718                try {
9719                    List apps = AppGlobals.getPackageManager().
9720                        getPersistentApplications(STOCK_PM_FLAGS);
9721                    if (apps != null) {
9722                        int N = apps.size();
9723                        int i;
9724                        for (i=0; i<N; i++) {
9725                            ApplicationInfo info
9726                                = (ApplicationInfo)apps.get(i);
9727                            if (info != null &&
9728                                    !info.packageName.equals("android")) {
9729                                addAppLocked(info, false);
9730                            }
9731                        }
9732                    }
9733                } catch (RemoteException ex) {
9734                    // pm is in same process, this will never happen.
9735                }
9736            }
9737
9738            // Start up initial activity.
9739            mBooting = true;
9740
9741            try {
9742                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9743                    Message msg = Message.obtain();
9744                    msg.what = SHOW_UID_ERROR_MSG;
9745                    mHandler.sendMessage(msg);
9746                }
9747            } catch (RemoteException e) {
9748            }
9749
9750            long ident = Binder.clearCallingIdentity();
9751            try {
9752                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9753                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9754                        | Intent.FLAG_RECEIVER_FOREGROUND);
9755                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9756                broadcastIntentLocked(null, null, intent,
9757                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9758                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9759                intent = new Intent(Intent.ACTION_USER_STARTING);
9760                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9761                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9762                broadcastIntentLocked(null, null, intent,
9763                        null, new IIntentReceiver.Stub() {
9764                            @Override
9765                            public void performReceive(Intent intent, int resultCode, String data,
9766                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9767                                    throws RemoteException {
9768                            }
9769                        }, 0, null, null,
9770                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9771                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9772            } catch (Throwable t) {
9773                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9774            } finally {
9775                Binder.restoreCallingIdentity(ident);
9776            }
9777            mStackSupervisor.resumeTopActivitiesLocked();
9778            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9779        }
9780    }
9781
9782    private boolean makeAppCrashingLocked(ProcessRecord app,
9783            String shortMsg, String longMsg, String stackTrace) {
9784        app.crashing = true;
9785        app.crashingReport = generateProcessError(app,
9786                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9787        startAppProblemLocked(app);
9788        app.stopFreezingAllLocked();
9789        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9790    }
9791
9792    private void makeAppNotRespondingLocked(ProcessRecord app,
9793            String activity, String shortMsg, String longMsg) {
9794        app.notResponding = true;
9795        app.notRespondingReport = generateProcessError(app,
9796                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9797                activity, shortMsg, longMsg, null);
9798        startAppProblemLocked(app);
9799        app.stopFreezingAllLocked();
9800    }
9801
9802    /**
9803     * Generate a process error record, suitable for attachment to a ProcessRecord.
9804     *
9805     * @param app The ProcessRecord in which the error occurred.
9806     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9807     *                      ActivityManager.AppErrorStateInfo
9808     * @param activity The activity associated with the crash, if known.
9809     * @param shortMsg Short message describing the crash.
9810     * @param longMsg Long message describing the crash.
9811     * @param stackTrace Full crash stack trace, may be null.
9812     *
9813     * @return Returns a fully-formed AppErrorStateInfo record.
9814     */
9815    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9816            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9817        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9818
9819        report.condition = condition;
9820        report.processName = app.processName;
9821        report.pid = app.pid;
9822        report.uid = app.info.uid;
9823        report.tag = activity;
9824        report.shortMsg = shortMsg;
9825        report.longMsg = longMsg;
9826        report.stackTrace = stackTrace;
9827
9828        return report;
9829    }
9830
9831    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9832        synchronized (this) {
9833            app.crashing = false;
9834            app.crashingReport = null;
9835            app.notResponding = false;
9836            app.notRespondingReport = null;
9837            if (app.anrDialog == fromDialog) {
9838                app.anrDialog = null;
9839            }
9840            if (app.waitDialog == fromDialog) {
9841                app.waitDialog = null;
9842            }
9843            if (app.pid > 0 && app.pid != MY_PID) {
9844                handleAppCrashLocked(app, null, null, null);
9845                killUnneededProcessLocked(app, "user request after error");
9846            }
9847        }
9848    }
9849
9850    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9851            String stackTrace) {
9852        long now = SystemClock.uptimeMillis();
9853
9854        Long crashTime;
9855        if (!app.isolated) {
9856            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9857        } else {
9858            crashTime = null;
9859        }
9860        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9861            // This process loses!
9862            Slog.w(TAG, "Process " + app.info.processName
9863                    + " has crashed too many times: killing!");
9864            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9865                    app.userId, app.info.processName, app.uid);
9866            mStackSupervisor.handleAppCrashLocked(app);
9867            if (!app.persistent) {
9868                // We don't want to start this process again until the user
9869                // explicitly does so...  but for persistent process, we really
9870                // need to keep it running.  If a persistent process is actually
9871                // repeatedly crashing, then badness for everyone.
9872                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9873                        app.info.processName);
9874                if (!app.isolated) {
9875                    // XXX We don't have a way to mark isolated processes
9876                    // as bad, since they don't have a peristent identity.
9877                    mBadProcesses.put(app.info.processName, app.uid,
9878                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9879                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9880                }
9881                app.bad = true;
9882                app.removed = true;
9883                // Don't let services in this process be restarted and potentially
9884                // annoy the user repeatedly.  Unless it is persistent, since those
9885                // processes run critical code.
9886                removeProcessLocked(app, false, false, "crash");
9887                mStackSupervisor.resumeTopActivitiesLocked();
9888                return false;
9889            }
9890            mStackSupervisor.resumeTopActivitiesLocked();
9891        } else {
9892            mStackSupervisor.finishTopRunningActivityLocked(app);
9893        }
9894
9895        // Bump up the crash count of any services currently running in the proc.
9896        for (int i=app.services.size()-1; i>=0; i--) {
9897            // Any services running in the application need to be placed
9898            // back in the pending list.
9899            ServiceRecord sr = app.services.valueAt(i);
9900            sr.crashCount++;
9901        }
9902
9903        // If the crashing process is what we consider to be the "home process" and it has been
9904        // replaced by a third-party app, clear the package preferred activities from packages
9905        // with a home activity running in the process to prevent a repeatedly crashing app
9906        // from blocking the user to manually clear the list.
9907        final ArrayList<ActivityRecord> activities = app.activities;
9908        if (app == mHomeProcess && activities.size() > 0
9909                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9910            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9911                final ActivityRecord r = activities.get(activityNdx);
9912                if (r.isHomeActivity()) {
9913                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9914                    try {
9915                        ActivityThread.getPackageManager()
9916                                .clearPackagePreferredActivities(r.packageName);
9917                    } catch (RemoteException c) {
9918                        // pm is in same process, this will never happen.
9919                    }
9920                }
9921            }
9922        }
9923
9924        if (!app.isolated) {
9925            // XXX Can't keep track of crash times for isolated processes,
9926            // because they don't have a perisistent identity.
9927            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9928        }
9929
9930        return true;
9931    }
9932
9933    void startAppProblemLocked(ProcessRecord app) {
9934        if (app.userId == mCurrentUserId) {
9935            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9936                    mContext, app.info.packageName, app.info.flags);
9937        } else {
9938            // If this app is not running under the current user, then we
9939            // can't give it a report button because that would require
9940            // launching the report UI under a different user.
9941            app.errorReportReceiver = null;
9942        }
9943        skipCurrentReceiverLocked(app);
9944    }
9945
9946    void skipCurrentReceiverLocked(ProcessRecord app) {
9947        for (BroadcastQueue queue : mBroadcastQueues) {
9948            queue.skipCurrentReceiverLocked(app);
9949        }
9950    }
9951
9952    /**
9953     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9954     * The application process will exit immediately after this call returns.
9955     * @param app object of the crashing app, null for the system server
9956     * @param crashInfo describing the exception
9957     */
9958    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9959        ProcessRecord r = findAppProcess(app, "Crash");
9960        final String processName = app == null ? "system_server"
9961                : (r == null ? "unknown" : r.processName);
9962
9963        handleApplicationCrashInner("crash", r, processName, crashInfo);
9964    }
9965
9966    /* Native crash reporting uses this inner version because it needs to be somewhat
9967     * decoupled from the AM-managed cleanup lifecycle
9968     */
9969    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9970            ApplicationErrorReport.CrashInfo crashInfo) {
9971        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9972                UserHandle.getUserId(Binder.getCallingUid()), processName,
9973                r == null ? -1 : r.info.flags,
9974                crashInfo.exceptionClassName,
9975                crashInfo.exceptionMessage,
9976                crashInfo.throwFileName,
9977                crashInfo.throwLineNumber);
9978
9979        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9980
9981        crashApplication(r, crashInfo);
9982    }
9983
9984    public void handleApplicationStrictModeViolation(
9985            IBinder app,
9986            int violationMask,
9987            StrictMode.ViolationInfo info) {
9988        ProcessRecord r = findAppProcess(app, "StrictMode");
9989        if (r == null) {
9990            return;
9991        }
9992
9993        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9994            Integer stackFingerprint = info.hashCode();
9995            boolean logIt = true;
9996            synchronized (mAlreadyLoggedViolatedStacks) {
9997                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9998                    logIt = false;
9999                    // TODO: sub-sample into EventLog for these, with
10000                    // the info.durationMillis?  Then we'd get
10001                    // the relative pain numbers, without logging all
10002                    // the stack traces repeatedly.  We'd want to do
10003                    // likewise in the client code, which also does
10004                    // dup suppression, before the Binder call.
10005                } else {
10006                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10007                        mAlreadyLoggedViolatedStacks.clear();
10008                    }
10009                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10010                }
10011            }
10012            if (logIt) {
10013                logStrictModeViolationToDropBox(r, info);
10014            }
10015        }
10016
10017        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10018            AppErrorResult result = new AppErrorResult();
10019            synchronized (this) {
10020                final long origId = Binder.clearCallingIdentity();
10021
10022                Message msg = Message.obtain();
10023                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10024                HashMap<String, Object> data = new HashMap<String, Object>();
10025                data.put("result", result);
10026                data.put("app", r);
10027                data.put("violationMask", violationMask);
10028                data.put("info", info);
10029                msg.obj = data;
10030                mHandler.sendMessage(msg);
10031
10032                Binder.restoreCallingIdentity(origId);
10033            }
10034            int res = result.get();
10035            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10036        }
10037    }
10038
10039    // Depending on the policy in effect, there could be a bunch of
10040    // these in quick succession so we try to batch these together to
10041    // minimize disk writes, number of dropbox entries, and maximize
10042    // compression, by having more fewer, larger records.
10043    private void logStrictModeViolationToDropBox(
10044            ProcessRecord process,
10045            StrictMode.ViolationInfo info) {
10046        if (info == null) {
10047            return;
10048        }
10049        final boolean isSystemApp = process == null ||
10050                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10051                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10052        final String processName = process == null ? "unknown" : process.processName;
10053        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10054        final DropBoxManager dbox = (DropBoxManager)
10055                mContext.getSystemService(Context.DROPBOX_SERVICE);
10056
10057        // Exit early if the dropbox isn't configured to accept this report type.
10058        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10059
10060        boolean bufferWasEmpty;
10061        boolean needsFlush;
10062        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10063        synchronized (sb) {
10064            bufferWasEmpty = sb.length() == 0;
10065            appendDropBoxProcessHeaders(process, processName, sb);
10066            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10067            sb.append("System-App: ").append(isSystemApp).append("\n");
10068            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10069            if (info.violationNumThisLoop != 0) {
10070                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10071            }
10072            if (info.numAnimationsRunning != 0) {
10073                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10074            }
10075            if (info.broadcastIntentAction != null) {
10076                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10077            }
10078            if (info.durationMillis != -1) {
10079                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10080            }
10081            if (info.numInstances != -1) {
10082                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10083            }
10084            if (info.tags != null) {
10085                for (String tag : info.tags) {
10086                    sb.append("Span-Tag: ").append(tag).append("\n");
10087                }
10088            }
10089            sb.append("\n");
10090            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10091                sb.append(info.crashInfo.stackTrace);
10092            }
10093            sb.append("\n");
10094
10095            // Only buffer up to ~64k.  Various logging bits truncate
10096            // things at 128k.
10097            needsFlush = (sb.length() > 64 * 1024);
10098        }
10099
10100        // Flush immediately if the buffer's grown too large, or this
10101        // is a non-system app.  Non-system apps are isolated with a
10102        // different tag & policy and not batched.
10103        //
10104        // Batching is useful during internal testing with
10105        // StrictMode settings turned up high.  Without batching,
10106        // thousands of separate files could be created on boot.
10107        if (!isSystemApp || needsFlush) {
10108            new Thread("Error dump: " + dropboxTag) {
10109                @Override
10110                public void run() {
10111                    String report;
10112                    synchronized (sb) {
10113                        report = sb.toString();
10114                        sb.delete(0, sb.length());
10115                        sb.trimToSize();
10116                    }
10117                    if (report.length() != 0) {
10118                        dbox.addText(dropboxTag, report);
10119                    }
10120                }
10121            }.start();
10122            return;
10123        }
10124
10125        // System app batching:
10126        if (!bufferWasEmpty) {
10127            // An existing dropbox-writing thread is outstanding, so
10128            // we don't need to start it up.  The existing thread will
10129            // catch the buffer appends we just did.
10130            return;
10131        }
10132
10133        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10134        // (After this point, we shouldn't access AMS internal data structures.)
10135        new Thread("Error dump: " + dropboxTag) {
10136            @Override
10137            public void run() {
10138                // 5 second sleep to let stacks arrive and be batched together
10139                try {
10140                    Thread.sleep(5000);  // 5 seconds
10141                } catch (InterruptedException e) {}
10142
10143                String errorReport;
10144                synchronized (mStrictModeBuffer) {
10145                    errorReport = mStrictModeBuffer.toString();
10146                    if (errorReport.length() == 0) {
10147                        return;
10148                    }
10149                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10150                    mStrictModeBuffer.trimToSize();
10151                }
10152                dbox.addText(dropboxTag, errorReport);
10153            }
10154        }.start();
10155    }
10156
10157    /**
10158     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10159     * @param app object of the crashing app, null for the system server
10160     * @param tag reported by the caller
10161     * @param crashInfo describing the context of the error
10162     * @return true if the process should exit immediately (WTF is fatal)
10163     */
10164    public boolean handleApplicationWtf(IBinder app, String tag,
10165            ApplicationErrorReport.CrashInfo crashInfo) {
10166        ProcessRecord r = findAppProcess(app, "WTF");
10167        final String processName = app == null ? "system_server"
10168                : (r == null ? "unknown" : r.processName);
10169
10170        EventLog.writeEvent(EventLogTags.AM_WTF,
10171                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10172                processName,
10173                r == null ? -1 : r.info.flags,
10174                tag, crashInfo.exceptionMessage);
10175
10176        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10177
10178        if (r != null && r.pid != Process.myPid() &&
10179                Settings.Global.getInt(mContext.getContentResolver(),
10180                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10181            crashApplication(r, crashInfo);
10182            return true;
10183        } else {
10184            return false;
10185        }
10186    }
10187
10188    /**
10189     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10190     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10191     */
10192    private ProcessRecord findAppProcess(IBinder app, String reason) {
10193        if (app == null) {
10194            return null;
10195        }
10196
10197        synchronized (this) {
10198            final int NP = mProcessNames.getMap().size();
10199            for (int ip=0; ip<NP; ip++) {
10200                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10201                final int NA = apps.size();
10202                for (int ia=0; ia<NA; ia++) {
10203                    ProcessRecord p = apps.valueAt(ia);
10204                    if (p.thread != null && p.thread.asBinder() == app) {
10205                        return p;
10206                    }
10207                }
10208            }
10209
10210            Slog.w(TAG, "Can't find mystery application for " + reason
10211                    + " from pid=" + Binder.getCallingPid()
10212                    + " uid=" + Binder.getCallingUid() + ": " + app);
10213            return null;
10214        }
10215    }
10216
10217    /**
10218     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10219     * to append various headers to the dropbox log text.
10220     */
10221    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10222            StringBuilder sb) {
10223        // Watchdog thread ends up invoking this function (with
10224        // a null ProcessRecord) to add the stack file to dropbox.
10225        // Do not acquire a lock on this (am) in such cases, as it
10226        // could cause a potential deadlock, if and when watchdog
10227        // is invoked due to unavailability of lock on am and it
10228        // would prevent watchdog from killing system_server.
10229        if (process == null) {
10230            sb.append("Process: ").append(processName).append("\n");
10231            return;
10232        }
10233        // Note: ProcessRecord 'process' is guarded by the service
10234        // instance.  (notably process.pkgList, which could otherwise change
10235        // concurrently during execution of this method)
10236        synchronized (this) {
10237            sb.append("Process: ").append(processName).append("\n");
10238            int flags = process.info.flags;
10239            IPackageManager pm = AppGlobals.getPackageManager();
10240            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10241            for (int ip=0; ip<process.pkgList.size(); ip++) {
10242                String pkg = process.pkgList.keyAt(ip);
10243                sb.append("Package: ").append(pkg);
10244                try {
10245                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10246                    if (pi != null) {
10247                        sb.append(" v").append(pi.versionCode);
10248                        if (pi.versionName != null) {
10249                            sb.append(" (").append(pi.versionName).append(")");
10250                        }
10251                    }
10252                } catch (RemoteException e) {
10253                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10254                }
10255                sb.append("\n");
10256            }
10257        }
10258    }
10259
10260    private static String processClass(ProcessRecord process) {
10261        if (process == null || process.pid == MY_PID) {
10262            return "system_server";
10263        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10264            return "system_app";
10265        } else {
10266            return "data_app";
10267        }
10268    }
10269
10270    /**
10271     * Write a description of an error (crash, WTF, ANR) to the drop box.
10272     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10273     * @param process which caused the error, null means the system server
10274     * @param activity which triggered the error, null if unknown
10275     * @param parent activity related to the error, null if unknown
10276     * @param subject line related to the error, null if absent
10277     * @param report in long form describing the error, null if absent
10278     * @param logFile to include in the report, null if none
10279     * @param crashInfo giving an application stack trace, null if absent
10280     */
10281    public void addErrorToDropBox(String eventType,
10282            ProcessRecord process, String processName, ActivityRecord activity,
10283            ActivityRecord parent, String subject,
10284            final String report, final File logFile,
10285            final ApplicationErrorReport.CrashInfo crashInfo) {
10286        // NOTE -- this must never acquire the ActivityManagerService lock,
10287        // otherwise the watchdog may be prevented from resetting the system.
10288
10289        final String dropboxTag = processClass(process) + "_" + eventType;
10290        final DropBoxManager dbox = (DropBoxManager)
10291                mContext.getSystemService(Context.DROPBOX_SERVICE);
10292
10293        // Exit early if the dropbox isn't configured to accept this report type.
10294        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10295
10296        final StringBuilder sb = new StringBuilder(1024);
10297        appendDropBoxProcessHeaders(process, processName, sb);
10298        if (activity != null) {
10299            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10300        }
10301        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10302            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10303        }
10304        if (parent != null && parent != activity) {
10305            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10306        }
10307        if (subject != null) {
10308            sb.append("Subject: ").append(subject).append("\n");
10309        }
10310        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10311        if (Debug.isDebuggerConnected()) {
10312            sb.append("Debugger: Connected\n");
10313        }
10314        sb.append("\n");
10315
10316        // Do the rest in a worker thread to avoid blocking the caller on I/O
10317        // (After this point, we shouldn't access AMS internal data structures.)
10318        Thread worker = new Thread("Error dump: " + dropboxTag) {
10319            @Override
10320            public void run() {
10321                if (report != null) {
10322                    sb.append(report);
10323                }
10324                if (logFile != null) {
10325                    try {
10326                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10327                                    "\n\n[[TRUNCATED]]"));
10328                    } catch (IOException e) {
10329                        Slog.e(TAG, "Error reading " + logFile, e);
10330                    }
10331                }
10332                if (crashInfo != null && crashInfo.stackTrace != null) {
10333                    sb.append(crashInfo.stackTrace);
10334                }
10335
10336                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10337                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10338                if (lines > 0) {
10339                    sb.append("\n");
10340
10341                    // Merge several logcat streams, and take the last N lines
10342                    InputStreamReader input = null;
10343                    try {
10344                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10345                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10346                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10347
10348                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10349                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10350                        input = new InputStreamReader(logcat.getInputStream());
10351
10352                        int num;
10353                        char[] buf = new char[8192];
10354                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10355                    } catch (IOException e) {
10356                        Slog.e(TAG, "Error running logcat", e);
10357                    } finally {
10358                        if (input != null) try { input.close(); } catch (IOException e) {}
10359                    }
10360                }
10361
10362                dbox.addText(dropboxTag, sb.toString());
10363            }
10364        };
10365
10366        if (process == null) {
10367            // If process is null, we are being called from some internal code
10368            // and may be about to die -- run this synchronously.
10369            worker.run();
10370        } else {
10371            worker.start();
10372        }
10373    }
10374
10375    /**
10376     * Bring up the "unexpected error" dialog box for a crashing app.
10377     * Deal with edge cases (intercepts from instrumented applications,
10378     * ActivityController, error intent receivers, that sort of thing).
10379     * @param r the application crashing
10380     * @param crashInfo describing the failure
10381     */
10382    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10383        long timeMillis = System.currentTimeMillis();
10384        String shortMsg = crashInfo.exceptionClassName;
10385        String longMsg = crashInfo.exceptionMessage;
10386        String stackTrace = crashInfo.stackTrace;
10387        if (shortMsg != null && longMsg != null) {
10388            longMsg = shortMsg + ": " + longMsg;
10389        } else if (shortMsg != null) {
10390            longMsg = shortMsg;
10391        }
10392
10393        AppErrorResult result = new AppErrorResult();
10394        synchronized (this) {
10395            if (mController != null) {
10396                try {
10397                    String name = r != null ? r.processName : null;
10398                    int pid = r != null ? r.pid : Binder.getCallingPid();
10399                    if (!mController.appCrashed(name, pid,
10400                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10401                        Slog.w(TAG, "Force-killing crashed app " + name
10402                                + " at watcher's request");
10403                        Process.killProcess(pid);
10404                        return;
10405                    }
10406                } catch (RemoteException e) {
10407                    mController = null;
10408                    Watchdog.getInstance().setActivityController(null);
10409                }
10410            }
10411
10412            final long origId = Binder.clearCallingIdentity();
10413
10414            // If this process is running instrumentation, finish it.
10415            if (r != null && r.instrumentationClass != null) {
10416                Slog.w(TAG, "Error in app " + r.processName
10417                      + " running instrumentation " + r.instrumentationClass + ":");
10418                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10419                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10420                Bundle info = new Bundle();
10421                info.putString("shortMsg", shortMsg);
10422                info.putString("longMsg", longMsg);
10423                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10424                Binder.restoreCallingIdentity(origId);
10425                return;
10426            }
10427
10428            // If we can't identify the process or it's already exceeded its crash quota,
10429            // quit right away without showing a crash dialog.
10430            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10431                Binder.restoreCallingIdentity(origId);
10432                return;
10433            }
10434
10435            Message msg = Message.obtain();
10436            msg.what = SHOW_ERROR_MSG;
10437            HashMap data = new HashMap();
10438            data.put("result", result);
10439            data.put("app", r);
10440            msg.obj = data;
10441            mHandler.sendMessage(msg);
10442
10443            Binder.restoreCallingIdentity(origId);
10444        }
10445
10446        int res = result.get();
10447
10448        Intent appErrorIntent = null;
10449        synchronized (this) {
10450            if (r != null && !r.isolated) {
10451                // XXX Can't keep track of crash time for isolated processes,
10452                // since they don't have a persistent identity.
10453                mProcessCrashTimes.put(r.info.processName, r.uid,
10454                        SystemClock.uptimeMillis());
10455            }
10456            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10457                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10458            }
10459        }
10460
10461        if (appErrorIntent != null) {
10462            try {
10463                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10464            } catch (ActivityNotFoundException e) {
10465                Slog.w(TAG, "bug report receiver dissappeared", e);
10466            }
10467        }
10468    }
10469
10470    Intent createAppErrorIntentLocked(ProcessRecord r,
10471            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10472        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10473        if (report == null) {
10474            return null;
10475        }
10476        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10477        result.setComponent(r.errorReportReceiver);
10478        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10479        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10480        return result;
10481    }
10482
10483    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10484            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10485        if (r.errorReportReceiver == null) {
10486            return null;
10487        }
10488
10489        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10490            return null;
10491        }
10492
10493        ApplicationErrorReport report = new ApplicationErrorReport();
10494        report.packageName = r.info.packageName;
10495        report.installerPackageName = r.errorReportReceiver.getPackageName();
10496        report.processName = r.processName;
10497        report.time = timeMillis;
10498        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10499
10500        if (r.crashing || r.forceCrashReport) {
10501            report.type = ApplicationErrorReport.TYPE_CRASH;
10502            report.crashInfo = crashInfo;
10503        } else if (r.notResponding) {
10504            report.type = ApplicationErrorReport.TYPE_ANR;
10505            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10506
10507            report.anrInfo.activity = r.notRespondingReport.tag;
10508            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10509            report.anrInfo.info = r.notRespondingReport.longMsg;
10510        }
10511
10512        return report;
10513    }
10514
10515    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10516        enforceNotIsolatedCaller("getProcessesInErrorState");
10517        // assume our apps are happy - lazy create the list
10518        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10519
10520        final boolean allUsers = ActivityManager.checkUidPermission(
10521                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10522                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10523        int userId = UserHandle.getUserId(Binder.getCallingUid());
10524
10525        synchronized (this) {
10526
10527            // iterate across all processes
10528            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10529                ProcessRecord app = mLruProcesses.get(i);
10530                if (!allUsers && app.userId != userId) {
10531                    continue;
10532                }
10533                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10534                    // This one's in trouble, so we'll generate a report for it
10535                    // crashes are higher priority (in case there's a crash *and* an anr)
10536                    ActivityManager.ProcessErrorStateInfo report = null;
10537                    if (app.crashing) {
10538                        report = app.crashingReport;
10539                    } else if (app.notResponding) {
10540                        report = app.notRespondingReport;
10541                    }
10542
10543                    if (report != null) {
10544                        if (errList == null) {
10545                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10546                        }
10547                        errList.add(report);
10548                    } else {
10549                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10550                                " crashing = " + app.crashing +
10551                                " notResponding = " + app.notResponding);
10552                    }
10553                }
10554            }
10555        }
10556
10557        return errList;
10558    }
10559
10560    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10561        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10562            if (currApp != null) {
10563                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10564            }
10565            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10566        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10567            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10568        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10569            if (currApp != null) {
10570                currApp.lru = 0;
10571            }
10572            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10573        } else if (adj >= ProcessList.SERVICE_ADJ) {
10574            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10575        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10576            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10577        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10578            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10579        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10580            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10581        } else {
10582            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10583        }
10584    }
10585
10586    private void fillInProcMemInfo(ProcessRecord app,
10587            ActivityManager.RunningAppProcessInfo outInfo) {
10588        outInfo.pid = app.pid;
10589        outInfo.uid = app.info.uid;
10590        if (mHeavyWeightProcess == app) {
10591            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10592        }
10593        if (app.persistent) {
10594            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10595        }
10596        if (app.activities.size() > 0) {
10597            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10598        }
10599        outInfo.lastTrimLevel = app.trimMemoryLevel;
10600        int adj = app.curAdj;
10601        outInfo.importance = oomAdjToImportance(adj, outInfo);
10602        outInfo.importanceReasonCode = app.adjTypeCode;
10603        outInfo.processState = app.curProcState;
10604    }
10605
10606    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10607        enforceNotIsolatedCaller("getRunningAppProcesses");
10608        // Lazy instantiation of list
10609        List<ActivityManager.RunningAppProcessInfo> runList = null;
10610        final boolean allUsers = ActivityManager.checkUidPermission(
10611                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10612                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10613        int userId = UserHandle.getUserId(Binder.getCallingUid());
10614        synchronized (this) {
10615            // Iterate across all processes
10616            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10617                ProcessRecord app = mLruProcesses.get(i);
10618                if (!allUsers && app.userId != userId) {
10619                    continue;
10620                }
10621                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10622                    // Generate process state info for running application
10623                    ActivityManager.RunningAppProcessInfo currApp =
10624                        new ActivityManager.RunningAppProcessInfo(app.processName,
10625                                app.pid, app.getPackageList());
10626                    fillInProcMemInfo(app, currApp);
10627                    if (app.adjSource instanceof ProcessRecord) {
10628                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10629                        currApp.importanceReasonImportance = oomAdjToImportance(
10630                                app.adjSourceOom, null);
10631                    } else if (app.adjSource instanceof ActivityRecord) {
10632                        ActivityRecord r = (ActivityRecord)app.adjSource;
10633                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10634                    }
10635                    if (app.adjTarget instanceof ComponentName) {
10636                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10637                    }
10638                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10639                    //        + " lru=" + currApp.lru);
10640                    if (runList == null) {
10641                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10642                    }
10643                    runList.add(currApp);
10644                }
10645            }
10646        }
10647        return runList;
10648    }
10649
10650    public List<ApplicationInfo> getRunningExternalApplications() {
10651        enforceNotIsolatedCaller("getRunningExternalApplications");
10652        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10653        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10654        if (runningApps != null && runningApps.size() > 0) {
10655            Set<String> extList = new HashSet<String>();
10656            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10657                if (app.pkgList != null) {
10658                    for (String pkg : app.pkgList) {
10659                        extList.add(pkg);
10660                    }
10661                }
10662            }
10663            IPackageManager pm = AppGlobals.getPackageManager();
10664            for (String pkg : extList) {
10665                try {
10666                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10667                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10668                        retList.add(info);
10669                    }
10670                } catch (RemoteException e) {
10671                }
10672            }
10673        }
10674        return retList;
10675    }
10676
10677    @Override
10678    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10679        enforceNotIsolatedCaller("getMyMemoryState");
10680        synchronized (this) {
10681            ProcessRecord proc;
10682            synchronized (mPidsSelfLocked) {
10683                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10684            }
10685            fillInProcMemInfo(proc, outInfo);
10686        }
10687    }
10688
10689    @Override
10690    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10691        if (checkCallingPermission(android.Manifest.permission.DUMP)
10692                != PackageManager.PERMISSION_GRANTED) {
10693            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10694                    + Binder.getCallingPid()
10695                    + ", uid=" + Binder.getCallingUid()
10696                    + " without permission "
10697                    + android.Manifest.permission.DUMP);
10698            return;
10699        }
10700
10701        boolean dumpAll = false;
10702        boolean dumpClient = false;
10703        String dumpPackage = null;
10704
10705        int opti = 0;
10706        while (opti < args.length) {
10707            String opt = args[opti];
10708            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10709                break;
10710            }
10711            opti++;
10712            if ("-a".equals(opt)) {
10713                dumpAll = true;
10714            } else if ("-c".equals(opt)) {
10715                dumpClient = true;
10716            } else if ("-h".equals(opt)) {
10717                pw.println("Activity manager dump options:");
10718                pw.println("  [-a] [-c] [-h] [cmd] ...");
10719                pw.println("  cmd may be one of:");
10720                pw.println("    a[ctivities]: activity stack state");
10721                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10722                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10723                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10724                pw.println("    o[om]: out of memory management");
10725                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10726                pw.println("    provider [COMP_SPEC]: provider client-side state");
10727                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10728                pw.println("    service [COMP_SPEC]: service client-side state");
10729                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10730                pw.println("    all: dump all activities");
10731                pw.println("    top: dump the top activity");
10732                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10733                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10734                pw.println("    a partial substring in a component name, a");
10735                pw.println("    hex object identifier.");
10736                pw.println("  -a: include all available server state.");
10737                pw.println("  -c: include client state.");
10738                return;
10739            } else {
10740                pw.println("Unknown argument: " + opt + "; use -h for help");
10741            }
10742        }
10743
10744        long origId = Binder.clearCallingIdentity();
10745        boolean more = false;
10746        // Is the caller requesting to dump a particular piece of data?
10747        if (opti < args.length) {
10748            String cmd = args[opti];
10749            opti++;
10750            if ("activities".equals(cmd) || "a".equals(cmd)) {
10751                synchronized (this) {
10752                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10753                }
10754            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10755                String[] newArgs;
10756                String name;
10757                if (opti >= args.length) {
10758                    name = null;
10759                    newArgs = EMPTY_STRING_ARRAY;
10760                } else {
10761                    name = args[opti];
10762                    opti++;
10763                    newArgs = new String[args.length - opti];
10764                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10765                            args.length - opti);
10766                }
10767                synchronized (this) {
10768                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10769                }
10770            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10771                String[] newArgs;
10772                String name;
10773                if (opti >= args.length) {
10774                    name = null;
10775                    newArgs = EMPTY_STRING_ARRAY;
10776                } else {
10777                    name = args[opti];
10778                    opti++;
10779                    newArgs = new String[args.length - opti];
10780                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10781                            args.length - opti);
10782                }
10783                synchronized (this) {
10784                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10785                }
10786            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10787                String[] newArgs;
10788                String name;
10789                if (opti >= args.length) {
10790                    name = null;
10791                    newArgs = EMPTY_STRING_ARRAY;
10792                } else {
10793                    name = args[opti];
10794                    opti++;
10795                    newArgs = new String[args.length - opti];
10796                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10797                            args.length - opti);
10798                }
10799                synchronized (this) {
10800                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10801                }
10802            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10803                synchronized (this) {
10804                    dumpOomLocked(fd, pw, args, opti, true);
10805                }
10806            } else if ("provider".equals(cmd)) {
10807                String[] newArgs;
10808                String name;
10809                if (opti >= args.length) {
10810                    name = null;
10811                    newArgs = EMPTY_STRING_ARRAY;
10812                } else {
10813                    name = args[opti];
10814                    opti++;
10815                    newArgs = new String[args.length - opti];
10816                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10817                }
10818                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10819                    pw.println("No providers match: " + name);
10820                    pw.println("Use -h for help.");
10821                }
10822            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10823                synchronized (this) {
10824                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10825                }
10826            } else if ("service".equals(cmd)) {
10827                String[] newArgs;
10828                String name;
10829                if (opti >= args.length) {
10830                    name = null;
10831                    newArgs = EMPTY_STRING_ARRAY;
10832                } else {
10833                    name = args[opti];
10834                    opti++;
10835                    newArgs = new String[args.length - opti];
10836                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10837                            args.length - opti);
10838                }
10839                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10840                    pw.println("No services match: " + name);
10841                    pw.println("Use -h for help.");
10842                }
10843            } else if ("package".equals(cmd)) {
10844                String[] newArgs;
10845                if (opti >= args.length) {
10846                    pw.println("package: no package name specified");
10847                    pw.println("Use -h for help.");
10848                } else {
10849                    dumpPackage = args[opti];
10850                    opti++;
10851                    newArgs = new String[args.length - opti];
10852                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10853                            args.length - opti);
10854                    args = newArgs;
10855                    opti = 0;
10856                    more = true;
10857                }
10858            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10859                synchronized (this) {
10860                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10861                }
10862            } else {
10863                // Dumping a single activity?
10864                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10865                    pw.println("Bad activity command, or no activities match: " + cmd);
10866                    pw.println("Use -h for help.");
10867                }
10868            }
10869            if (!more) {
10870                Binder.restoreCallingIdentity(origId);
10871                return;
10872            }
10873        }
10874
10875        // No piece of data specified, dump everything.
10876        synchronized (this) {
10877            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10878            pw.println();
10879            if (dumpAll) {
10880                pw.println("-------------------------------------------------------------------------------");
10881            }
10882            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10883            pw.println();
10884            if (dumpAll) {
10885                pw.println("-------------------------------------------------------------------------------");
10886            }
10887            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10888            pw.println();
10889            if (dumpAll) {
10890                pw.println("-------------------------------------------------------------------------------");
10891            }
10892            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10893            pw.println();
10894            if (dumpAll) {
10895                pw.println("-------------------------------------------------------------------------------");
10896            }
10897            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10898            pw.println();
10899            if (dumpAll) {
10900                pw.println("-------------------------------------------------------------------------------");
10901            }
10902            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10903        }
10904        Binder.restoreCallingIdentity(origId);
10905    }
10906
10907    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10908            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10909        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10910
10911        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10912                dumpPackage);
10913        boolean needSep = printedAnything;
10914
10915        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10916                dumpPackage, needSep, "  mFocusedActivity: ");
10917        if (printed) {
10918            printedAnything = true;
10919            needSep = false;
10920        }
10921
10922        if (dumpPackage == null) {
10923            if (needSep) {
10924                pw.println();
10925            }
10926            needSep = true;
10927            printedAnything = true;
10928            mStackSupervisor.dump(pw, "  ");
10929        }
10930
10931        if (mRecentTasks.size() > 0) {
10932            boolean printedHeader = false;
10933
10934            final int N = mRecentTasks.size();
10935            for (int i=0; i<N; i++) {
10936                TaskRecord tr = mRecentTasks.get(i);
10937                if (dumpPackage != null) {
10938                    if (tr.realActivity == null ||
10939                            !dumpPackage.equals(tr.realActivity)) {
10940                        continue;
10941                    }
10942                }
10943                if (!printedHeader) {
10944                    if (needSep) {
10945                        pw.println();
10946                    }
10947                    pw.println("  Recent tasks:");
10948                    printedHeader = true;
10949                    printedAnything = true;
10950                }
10951                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10952                        pw.println(tr);
10953                if (dumpAll) {
10954                    mRecentTasks.get(i).dump(pw, "    ");
10955                }
10956            }
10957        }
10958
10959        if (!printedAnything) {
10960            pw.println("  (nothing)");
10961        }
10962    }
10963
10964    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10965            int opti, boolean dumpAll, String dumpPackage) {
10966        boolean needSep = false;
10967        boolean printedAnything = false;
10968        int numPers = 0;
10969
10970        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10971
10972        if (dumpAll) {
10973            final int NP = mProcessNames.getMap().size();
10974            for (int ip=0; ip<NP; ip++) {
10975                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10976                final int NA = procs.size();
10977                for (int ia=0; ia<NA; ia++) {
10978                    ProcessRecord r = procs.valueAt(ia);
10979                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10980                        continue;
10981                    }
10982                    if (!needSep) {
10983                        pw.println("  All known processes:");
10984                        needSep = true;
10985                        printedAnything = true;
10986                    }
10987                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10988                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10989                        pw.print(" "); pw.println(r);
10990                    r.dump(pw, "    ");
10991                    if (r.persistent) {
10992                        numPers++;
10993                    }
10994                }
10995            }
10996        }
10997
10998        if (mIsolatedProcesses.size() > 0) {
10999            boolean printed = false;
11000            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11001                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11002                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11003                    continue;
11004                }
11005                if (!printed) {
11006                    if (needSep) {
11007                        pw.println();
11008                    }
11009                    pw.println("  Isolated process list (sorted by uid):");
11010                    printedAnything = true;
11011                    printed = true;
11012                    needSep = true;
11013                }
11014                pw.println(String.format("%sIsolated #%2d: %s",
11015                        "    ", i, r.toString()));
11016            }
11017        }
11018
11019        if (mLruProcesses.size() > 0) {
11020            if (needSep) {
11021                pw.println();
11022            }
11023            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11024                    pw.print(" total, non-act at ");
11025                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11026                    pw.print(", non-svc at ");
11027                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11028                    pw.println("):");
11029            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11030            needSep = true;
11031            printedAnything = true;
11032        }
11033
11034        if (dumpAll || dumpPackage != null) {
11035            synchronized (mPidsSelfLocked) {
11036                boolean printed = false;
11037                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11038                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11039                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11040                        continue;
11041                    }
11042                    if (!printed) {
11043                        if (needSep) pw.println();
11044                        needSep = true;
11045                        pw.println("  PID mappings:");
11046                        printed = true;
11047                        printedAnything = true;
11048                    }
11049                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11050                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11051                }
11052            }
11053        }
11054
11055        if (mForegroundProcesses.size() > 0) {
11056            synchronized (mPidsSelfLocked) {
11057                boolean printed = false;
11058                for (int i=0; i<mForegroundProcesses.size(); i++) {
11059                    ProcessRecord r = mPidsSelfLocked.get(
11060                            mForegroundProcesses.valueAt(i).pid);
11061                    if (dumpPackage != null && (r == null
11062                            || !r.pkgList.containsKey(dumpPackage))) {
11063                        continue;
11064                    }
11065                    if (!printed) {
11066                        if (needSep) pw.println();
11067                        needSep = true;
11068                        pw.println("  Foreground Processes:");
11069                        printed = true;
11070                        printedAnything = true;
11071                    }
11072                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11073                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11074                }
11075            }
11076        }
11077
11078        if (mPersistentStartingProcesses.size() > 0) {
11079            if (needSep) pw.println();
11080            needSep = true;
11081            printedAnything = true;
11082            pw.println("  Persisent processes that are starting:");
11083            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11084                    "Starting Norm", "Restarting PERS", dumpPackage);
11085        }
11086
11087        if (mRemovedProcesses.size() > 0) {
11088            if (needSep) pw.println();
11089            needSep = true;
11090            printedAnything = true;
11091            pw.println("  Processes that are being removed:");
11092            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11093                    "Removed Norm", "Removed PERS", dumpPackage);
11094        }
11095
11096        if (mProcessesOnHold.size() > 0) {
11097            if (needSep) pw.println();
11098            needSep = true;
11099            printedAnything = true;
11100            pw.println("  Processes that are on old until the system is ready:");
11101            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11102                    "OnHold Norm", "OnHold PERS", dumpPackage);
11103        }
11104
11105        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11106
11107        if (mProcessCrashTimes.getMap().size() > 0) {
11108            boolean printed = false;
11109            long now = SystemClock.uptimeMillis();
11110            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11111            final int NP = pmap.size();
11112            for (int ip=0; ip<NP; ip++) {
11113                String pname = pmap.keyAt(ip);
11114                SparseArray<Long> uids = pmap.valueAt(ip);
11115                final int N = uids.size();
11116                for (int i=0; i<N; i++) {
11117                    int puid = uids.keyAt(i);
11118                    ProcessRecord r = mProcessNames.get(pname, puid);
11119                    if (dumpPackage != null && (r == null
11120                            || !r.pkgList.containsKey(dumpPackage))) {
11121                        continue;
11122                    }
11123                    if (!printed) {
11124                        if (needSep) pw.println();
11125                        needSep = true;
11126                        pw.println("  Time since processes crashed:");
11127                        printed = true;
11128                        printedAnything = true;
11129                    }
11130                    pw.print("    Process "); pw.print(pname);
11131                            pw.print(" uid "); pw.print(puid);
11132                            pw.print(": last crashed ");
11133                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11134                            pw.println(" ago");
11135                }
11136            }
11137        }
11138
11139        if (mBadProcesses.getMap().size() > 0) {
11140            boolean printed = false;
11141            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11142            final int NP = pmap.size();
11143            for (int ip=0; ip<NP; ip++) {
11144                String pname = pmap.keyAt(ip);
11145                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11146                final int N = uids.size();
11147                for (int i=0; i<N; i++) {
11148                    int puid = uids.keyAt(i);
11149                    ProcessRecord r = mProcessNames.get(pname, puid);
11150                    if (dumpPackage != null && (r == null
11151                            || !r.pkgList.containsKey(dumpPackage))) {
11152                        continue;
11153                    }
11154                    if (!printed) {
11155                        if (needSep) pw.println();
11156                        needSep = true;
11157                        pw.println("  Bad processes:");
11158                        printedAnything = true;
11159                    }
11160                    BadProcessInfo info = uids.valueAt(i);
11161                    pw.print("    Bad process "); pw.print(pname);
11162                            pw.print(" uid "); pw.print(puid);
11163                            pw.print(": crashed at time "); pw.println(info.time);
11164                    if (info.shortMsg != null) {
11165                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11166                    }
11167                    if (info.longMsg != null) {
11168                        pw.print("      Long msg: "); pw.println(info.longMsg);
11169                    }
11170                    if (info.stack != null) {
11171                        pw.println("      Stack:");
11172                        int lastPos = 0;
11173                        for (int pos=0; pos<info.stack.length(); pos++) {
11174                            if (info.stack.charAt(pos) == '\n') {
11175                                pw.print("        ");
11176                                pw.write(info.stack, lastPos, pos-lastPos);
11177                                pw.println();
11178                                lastPos = pos+1;
11179                            }
11180                        }
11181                        if (lastPos < info.stack.length()) {
11182                            pw.print("        ");
11183                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11184                            pw.println();
11185                        }
11186                    }
11187                }
11188            }
11189        }
11190
11191        if (dumpPackage == null) {
11192            pw.println();
11193            needSep = false;
11194            pw.println("  mStartedUsers:");
11195            for (int i=0; i<mStartedUsers.size(); i++) {
11196                UserStartedState uss = mStartedUsers.valueAt(i);
11197                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11198                        pw.print(": "); uss.dump("", pw);
11199            }
11200            pw.print("  mStartedUserArray: [");
11201            for (int i=0; i<mStartedUserArray.length; i++) {
11202                if (i > 0) pw.print(", ");
11203                pw.print(mStartedUserArray[i]);
11204            }
11205            pw.println("]");
11206            pw.print("  mUserLru: [");
11207            for (int i=0; i<mUserLru.size(); i++) {
11208                if (i > 0) pw.print(", ");
11209                pw.print(mUserLru.get(i));
11210            }
11211            pw.println("]");
11212            if (dumpAll) {
11213                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11214            }
11215        }
11216        if (mHomeProcess != null && (dumpPackage == null
11217                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11218            if (needSep) {
11219                pw.println();
11220                needSep = false;
11221            }
11222            pw.println("  mHomeProcess: " + mHomeProcess);
11223        }
11224        if (mPreviousProcess != null && (dumpPackage == null
11225                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11226            if (needSep) {
11227                pw.println();
11228                needSep = false;
11229            }
11230            pw.println("  mPreviousProcess: " + mPreviousProcess);
11231        }
11232        if (dumpAll) {
11233            StringBuilder sb = new StringBuilder(128);
11234            sb.append("  mPreviousProcessVisibleTime: ");
11235            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11236            pw.println(sb);
11237        }
11238        if (mHeavyWeightProcess != null && (dumpPackage == null
11239                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11240            if (needSep) {
11241                pw.println();
11242                needSep = false;
11243            }
11244            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11245        }
11246        if (dumpPackage == null) {
11247            pw.println("  mConfiguration: " + mConfiguration);
11248        }
11249        if (dumpAll) {
11250            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11251            if (mCompatModePackages.getPackages().size() > 0) {
11252                boolean printed = false;
11253                for (Map.Entry<String, Integer> entry
11254                        : mCompatModePackages.getPackages().entrySet()) {
11255                    String pkg = entry.getKey();
11256                    int mode = entry.getValue();
11257                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11258                        continue;
11259                    }
11260                    if (!printed) {
11261                        pw.println("  mScreenCompatPackages:");
11262                        printed = true;
11263                    }
11264                    pw.print("    "); pw.print(pkg); pw.print(": ");
11265                            pw.print(mode); pw.println();
11266                }
11267            }
11268        }
11269        if (dumpPackage == null) {
11270            if (mSleeping || mWentToSleep || mLockScreenShown) {
11271                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11272                        + " mLockScreenShown " + mLockScreenShown);
11273            }
11274            if (mShuttingDown || mRunningVoice) {
11275                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11276            }
11277        }
11278        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11279                || mOrigWaitForDebugger) {
11280            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11281                    || dumpPackage.equals(mOrigDebugApp)) {
11282                if (needSep) {
11283                    pw.println();
11284                    needSep = false;
11285                }
11286                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11287                        + " mDebugTransient=" + mDebugTransient
11288                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11289            }
11290        }
11291        if (mOpenGlTraceApp != null) {
11292            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11293                if (needSep) {
11294                    pw.println();
11295                    needSep = false;
11296                }
11297                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11298            }
11299        }
11300        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11301                || mProfileFd != null) {
11302            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11303                if (needSep) {
11304                    pw.println();
11305                    needSep = false;
11306                }
11307                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11308                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11309                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11310                        + mAutoStopProfiler);
11311            }
11312        }
11313        if (dumpPackage == null) {
11314            if (mAlwaysFinishActivities || mController != null) {
11315                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11316                        + " mController=" + mController);
11317            }
11318            if (dumpAll) {
11319                pw.println("  Total persistent processes: " + numPers);
11320                pw.println("  mProcessesReady=" + mProcessesReady
11321                        + " mSystemReady=" + mSystemReady);
11322                pw.println("  mBooting=" + mBooting
11323                        + " mBooted=" + mBooted
11324                        + " mFactoryTest=" + mFactoryTest);
11325                pw.print("  mLastPowerCheckRealtime=");
11326                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11327                        pw.println("");
11328                pw.print("  mLastPowerCheckUptime=");
11329                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11330                        pw.println("");
11331                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11332                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11333                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11334                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11335                        + " (" + mLruProcesses.size() + " total)"
11336                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11337                        + " mNumServiceProcs=" + mNumServiceProcs
11338                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11339                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11340                        + " mLastMemoryLevel" + mLastMemoryLevel
11341                        + " mLastNumProcesses" + mLastNumProcesses);
11342                long now = SystemClock.uptimeMillis();
11343                pw.print("  mLastIdleTime=");
11344                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11345                        pw.print(" mLowRamSinceLastIdle=");
11346                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11347                        pw.println();
11348            }
11349        }
11350
11351        if (!printedAnything) {
11352            pw.println("  (nothing)");
11353        }
11354    }
11355
11356    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11357            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11358        if (mProcessesToGc.size() > 0) {
11359            boolean printed = false;
11360            long now = SystemClock.uptimeMillis();
11361            for (int i=0; i<mProcessesToGc.size(); i++) {
11362                ProcessRecord proc = mProcessesToGc.get(i);
11363                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11364                    continue;
11365                }
11366                if (!printed) {
11367                    if (needSep) pw.println();
11368                    needSep = true;
11369                    pw.println("  Processes that are waiting to GC:");
11370                    printed = true;
11371                }
11372                pw.print("    Process "); pw.println(proc);
11373                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11374                        pw.print(", last gced=");
11375                        pw.print(now-proc.lastRequestedGc);
11376                        pw.print(" ms ago, last lowMem=");
11377                        pw.print(now-proc.lastLowMemory);
11378                        pw.println(" ms ago");
11379
11380            }
11381        }
11382        return needSep;
11383    }
11384
11385    void printOomLevel(PrintWriter pw, String name, int adj) {
11386        pw.print("    ");
11387        if (adj >= 0) {
11388            pw.print(' ');
11389            if (adj < 10) pw.print(' ');
11390        } else {
11391            if (adj > -10) pw.print(' ');
11392        }
11393        pw.print(adj);
11394        pw.print(": ");
11395        pw.print(name);
11396        pw.print(" (");
11397        pw.print(mProcessList.getMemLevel(adj)/1024);
11398        pw.println(" kB)");
11399    }
11400
11401    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11402            int opti, boolean dumpAll) {
11403        boolean needSep = false;
11404
11405        if (mLruProcesses.size() > 0) {
11406            if (needSep) pw.println();
11407            needSep = true;
11408            pw.println("  OOM levels:");
11409            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11410            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11411            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11412            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11413            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11414            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11415            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11416            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11417            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11418            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11419            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11420            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11421            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11422
11423            if (needSep) pw.println();
11424            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11425                    pw.print(" total, non-act at ");
11426                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11427                    pw.print(", non-svc at ");
11428                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11429                    pw.println("):");
11430            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11431            needSep = true;
11432        }
11433
11434        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11435
11436        pw.println();
11437        pw.println("  mHomeProcess: " + mHomeProcess);
11438        pw.println("  mPreviousProcess: " + mPreviousProcess);
11439        if (mHeavyWeightProcess != null) {
11440            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11441        }
11442
11443        return true;
11444    }
11445
11446    /**
11447     * There are three ways to call this:
11448     *  - no provider specified: dump all the providers
11449     *  - a flattened component name that matched an existing provider was specified as the
11450     *    first arg: dump that one provider
11451     *  - the first arg isn't the flattened component name of an existing provider:
11452     *    dump all providers whose component contains the first arg as a substring
11453     */
11454    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11455            int opti, boolean dumpAll) {
11456        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11457    }
11458
11459    static class ItemMatcher {
11460        ArrayList<ComponentName> components;
11461        ArrayList<String> strings;
11462        ArrayList<Integer> objects;
11463        boolean all;
11464
11465        ItemMatcher() {
11466            all = true;
11467        }
11468
11469        void build(String name) {
11470            ComponentName componentName = ComponentName.unflattenFromString(name);
11471            if (componentName != null) {
11472                if (components == null) {
11473                    components = new ArrayList<ComponentName>();
11474                }
11475                components.add(componentName);
11476                all = false;
11477            } else {
11478                int objectId = 0;
11479                // Not a '/' separated full component name; maybe an object ID?
11480                try {
11481                    objectId = Integer.parseInt(name, 16);
11482                    if (objects == null) {
11483                        objects = new ArrayList<Integer>();
11484                    }
11485                    objects.add(objectId);
11486                    all = false;
11487                } catch (RuntimeException e) {
11488                    // Not an integer; just do string match.
11489                    if (strings == null) {
11490                        strings = new ArrayList<String>();
11491                    }
11492                    strings.add(name);
11493                    all = false;
11494                }
11495            }
11496        }
11497
11498        int build(String[] args, int opti) {
11499            for (; opti<args.length; opti++) {
11500                String name = args[opti];
11501                if ("--".equals(name)) {
11502                    return opti+1;
11503                }
11504                build(name);
11505            }
11506            return opti;
11507        }
11508
11509        boolean match(Object object, ComponentName comp) {
11510            if (all) {
11511                return true;
11512            }
11513            if (components != null) {
11514                for (int i=0; i<components.size(); i++) {
11515                    if (components.get(i).equals(comp)) {
11516                        return true;
11517                    }
11518                }
11519            }
11520            if (objects != null) {
11521                for (int i=0; i<objects.size(); i++) {
11522                    if (System.identityHashCode(object) == objects.get(i)) {
11523                        return true;
11524                    }
11525                }
11526            }
11527            if (strings != null) {
11528                String flat = comp.flattenToString();
11529                for (int i=0; i<strings.size(); i++) {
11530                    if (flat.contains(strings.get(i))) {
11531                        return true;
11532                    }
11533                }
11534            }
11535            return false;
11536        }
11537    }
11538
11539    /**
11540     * There are three things that cmd can be:
11541     *  - a flattened component name that matches an existing activity
11542     *  - the cmd arg isn't the flattened component name of an existing activity:
11543     *    dump all activity whose component contains the cmd as a substring
11544     *  - A hex number of the ActivityRecord object instance.
11545     */
11546    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11547            int opti, boolean dumpAll) {
11548        ArrayList<ActivityRecord> activities;
11549
11550        synchronized (this) {
11551            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11552        }
11553
11554        if (activities.size() <= 0) {
11555            return false;
11556        }
11557
11558        String[] newArgs = new String[args.length - opti];
11559        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11560
11561        TaskRecord lastTask = null;
11562        boolean needSep = false;
11563        for (int i=activities.size()-1; i>=0; i--) {
11564            ActivityRecord r = activities.get(i);
11565            if (needSep) {
11566                pw.println();
11567            }
11568            needSep = true;
11569            synchronized (this) {
11570                if (lastTask != r.task) {
11571                    lastTask = r.task;
11572                    pw.print("TASK "); pw.print(lastTask.affinity);
11573                            pw.print(" id="); pw.println(lastTask.taskId);
11574                    if (dumpAll) {
11575                        lastTask.dump(pw, "  ");
11576                    }
11577                }
11578            }
11579            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11580        }
11581        return true;
11582    }
11583
11584    /**
11585     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11586     * there is a thread associated with the activity.
11587     */
11588    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11589            final ActivityRecord r, String[] args, boolean dumpAll) {
11590        String innerPrefix = prefix + "  ";
11591        synchronized (this) {
11592            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11593                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11594                    pw.print(" pid=");
11595                    if (r.app != null) pw.println(r.app.pid);
11596                    else pw.println("(not running)");
11597            if (dumpAll) {
11598                r.dump(pw, innerPrefix);
11599            }
11600        }
11601        if (r.app != null && r.app.thread != null) {
11602            // flush anything that is already in the PrintWriter since the thread is going
11603            // to write to the file descriptor directly
11604            pw.flush();
11605            try {
11606                TransferPipe tp = new TransferPipe();
11607                try {
11608                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11609                            r.appToken, innerPrefix, args);
11610                    tp.go(fd);
11611                } finally {
11612                    tp.kill();
11613                }
11614            } catch (IOException e) {
11615                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11616            } catch (RemoteException e) {
11617                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11618            }
11619        }
11620    }
11621
11622    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11623            int opti, boolean dumpAll, String dumpPackage) {
11624        boolean needSep = false;
11625        boolean onlyHistory = false;
11626        boolean printedAnything = false;
11627
11628        if ("history".equals(dumpPackage)) {
11629            if (opti < args.length && "-s".equals(args[opti])) {
11630                dumpAll = false;
11631            }
11632            onlyHistory = true;
11633            dumpPackage = null;
11634        }
11635
11636        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11637        if (!onlyHistory && dumpAll) {
11638            if (mRegisteredReceivers.size() > 0) {
11639                boolean printed = false;
11640                Iterator it = mRegisteredReceivers.values().iterator();
11641                while (it.hasNext()) {
11642                    ReceiverList r = (ReceiverList)it.next();
11643                    if (dumpPackage != null && (r.app == null ||
11644                            !dumpPackage.equals(r.app.info.packageName))) {
11645                        continue;
11646                    }
11647                    if (!printed) {
11648                        pw.println("  Registered Receivers:");
11649                        needSep = true;
11650                        printed = true;
11651                        printedAnything = true;
11652                    }
11653                    pw.print("  * "); pw.println(r);
11654                    r.dump(pw, "    ");
11655                }
11656            }
11657
11658            if (mReceiverResolver.dump(pw, needSep ?
11659                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11660                    "    ", dumpPackage, false)) {
11661                needSep = true;
11662                printedAnything = true;
11663            }
11664        }
11665
11666        for (BroadcastQueue q : mBroadcastQueues) {
11667            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11668            printedAnything |= needSep;
11669        }
11670
11671        needSep = true;
11672
11673        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11674            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11675                if (needSep) {
11676                    pw.println();
11677                }
11678                needSep = true;
11679                printedAnything = true;
11680                pw.print("  Sticky broadcasts for user ");
11681                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11682                StringBuilder sb = new StringBuilder(128);
11683                for (Map.Entry<String, ArrayList<Intent>> ent
11684                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11685                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11686                    if (dumpAll) {
11687                        pw.println(":");
11688                        ArrayList<Intent> intents = ent.getValue();
11689                        final int N = intents.size();
11690                        for (int i=0; i<N; i++) {
11691                            sb.setLength(0);
11692                            sb.append("    Intent: ");
11693                            intents.get(i).toShortString(sb, false, true, false, false);
11694                            pw.println(sb.toString());
11695                            Bundle bundle = intents.get(i).getExtras();
11696                            if (bundle != null) {
11697                                pw.print("      ");
11698                                pw.println(bundle.toString());
11699                            }
11700                        }
11701                    } else {
11702                        pw.println("");
11703                    }
11704                }
11705            }
11706        }
11707
11708        if (!onlyHistory && dumpAll) {
11709            pw.println();
11710            for (BroadcastQueue queue : mBroadcastQueues) {
11711                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11712                        + queue.mBroadcastsScheduled);
11713            }
11714            pw.println("  mHandler:");
11715            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11716            needSep = true;
11717            printedAnything = true;
11718        }
11719
11720        if (!printedAnything) {
11721            pw.println("  (nothing)");
11722        }
11723    }
11724
11725    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11726            int opti, boolean dumpAll, String dumpPackage) {
11727        boolean needSep;
11728        boolean printedAnything = false;
11729
11730        ItemMatcher matcher = new ItemMatcher();
11731        matcher.build(args, opti);
11732
11733        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11734
11735        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11736        printedAnything |= needSep;
11737
11738        if (mLaunchingProviders.size() > 0) {
11739            boolean printed = false;
11740            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11741                ContentProviderRecord r = mLaunchingProviders.get(i);
11742                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11743                    continue;
11744                }
11745                if (!printed) {
11746                    if (needSep) pw.println();
11747                    needSep = true;
11748                    pw.println("  Launching content providers:");
11749                    printed = true;
11750                    printedAnything = true;
11751                }
11752                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11753                        pw.println(r);
11754            }
11755        }
11756
11757        if (mGrantedUriPermissions.size() > 0) {
11758            boolean printed = false;
11759            int dumpUid = -2;
11760            if (dumpPackage != null) {
11761                try {
11762                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11763                } catch (NameNotFoundException e) {
11764                    dumpUid = -1;
11765                }
11766            }
11767            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11768                int uid = mGrantedUriPermissions.keyAt(i);
11769                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11770                    continue;
11771                }
11772                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11773                if (!printed) {
11774                    if (needSep) pw.println();
11775                    needSep = true;
11776                    pw.println("  Granted Uri Permissions:");
11777                    printed = true;
11778                    printedAnything = true;
11779                }
11780                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11781                for (UriPermission perm : perms.values()) {
11782                    pw.print("    "); pw.println(perm);
11783                    if (dumpAll) {
11784                        perm.dump(pw, "      ");
11785                    }
11786                }
11787            }
11788        }
11789
11790        if (!printedAnything) {
11791            pw.println("  (nothing)");
11792        }
11793    }
11794
11795    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11796            int opti, boolean dumpAll, String dumpPackage) {
11797        boolean printed = false;
11798
11799        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11800
11801        if (mIntentSenderRecords.size() > 0) {
11802            Iterator<WeakReference<PendingIntentRecord>> it
11803                    = mIntentSenderRecords.values().iterator();
11804            while (it.hasNext()) {
11805                WeakReference<PendingIntentRecord> ref = it.next();
11806                PendingIntentRecord rec = ref != null ? ref.get(): null;
11807                if (dumpPackage != null && (rec == null
11808                        || !dumpPackage.equals(rec.key.packageName))) {
11809                    continue;
11810                }
11811                printed = true;
11812                if (rec != null) {
11813                    pw.print("  * "); pw.println(rec);
11814                    if (dumpAll) {
11815                        rec.dump(pw, "    ");
11816                    }
11817                } else {
11818                    pw.print("  * "); pw.println(ref);
11819                }
11820            }
11821        }
11822
11823        if (!printed) {
11824            pw.println("  (nothing)");
11825        }
11826    }
11827
11828    private static final int dumpProcessList(PrintWriter pw,
11829            ActivityManagerService service, List list,
11830            String prefix, String normalLabel, String persistentLabel,
11831            String dumpPackage) {
11832        int numPers = 0;
11833        final int N = list.size()-1;
11834        for (int i=N; i>=0; i--) {
11835            ProcessRecord r = (ProcessRecord)list.get(i);
11836            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11837                continue;
11838            }
11839            pw.println(String.format("%s%s #%2d: %s",
11840                    prefix, (r.persistent ? persistentLabel : normalLabel),
11841                    i, r.toString()));
11842            if (r.persistent) {
11843                numPers++;
11844            }
11845        }
11846        return numPers;
11847    }
11848
11849    private static final boolean dumpProcessOomList(PrintWriter pw,
11850            ActivityManagerService service, List<ProcessRecord> origList,
11851            String prefix, String normalLabel, String persistentLabel,
11852            boolean inclDetails, String dumpPackage) {
11853
11854        ArrayList<Pair<ProcessRecord, Integer>> list
11855                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11856        for (int i=0; i<origList.size(); i++) {
11857            ProcessRecord r = origList.get(i);
11858            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11859                continue;
11860            }
11861            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11862        }
11863
11864        if (list.size() <= 0) {
11865            return false;
11866        }
11867
11868        Comparator<Pair<ProcessRecord, Integer>> comparator
11869                = new Comparator<Pair<ProcessRecord, Integer>>() {
11870            @Override
11871            public int compare(Pair<ProcessRecord, Integer> object1,
11872                    Pair<ProcessRecord, Integer> object2) {
11873                if (object1.first.setAdj != object2.first.setAdj) {
11874                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11875                }
11876                if (object1.second.intValue() != object2.second.intValue()) {
11877                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11878                }
11879                return 0;
11880            }
11881        };
11882
11883        Collections.sort(list, comparator);
11884
11885        final long curRealtime = SystemClock.elapsedRealtime();
11886        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11887        final long curUptime = SystemClock.uptimeMillis();
11888        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11889
11890        for (int i=list.size()-1; i>=0; i--) {
11891            ProcessRecord r = list.get(i).first;
11892            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11893            char schedGroup;
11894            switch (r.setSchedGroup) {
11895                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11896                    schedGroup = 'B';
11897                    break;
11898                case Process.THREAD_GROUP_DEFAULT:
11899                    schedGroup = 'F';
11900                    break;
11901                default:
11902                    schedGroup = '?';
11903                    break;
11904            }
11905            char foreground;
11906            if (r.foregroundActivities) {
11907                foreground = 'A';
11908            } else if (r.foregroundServices) {
11909                foreground = 'S';
11910            } else {
11911                foreground = ' ';
11912            }
11913            String procState = ProcessList.makeProcStateString(r.curProcState);
11914            pw.print(prefix);
11915            pw.print(r.persistent ? persistentLabel : normalLabel);
11916            pw.print(" #");
11917            int num = (origList.size()-1)-list.get(i).second;
11918            if (num < 10) pw.print(' ');
11919            pw.print(num);
11920            pw.print(": ");
11921            pw.print(oomAdj);
11922            pw.print(' ');
11923            pw.print(schedGroup);
11924            pw.print('/');
11925            pw.print(foreground);
11926            pw.print('/');
11927            pw.print(procState);
11928            pw.print(" trm:");
11929            if (r.trimMemoryLevel < 10) pw.print(' ');
11930            pw.print(r.trimMemoryLevel);
11931            pw.print(' ');
11932            pw.print(r.toShortString());
11933            pw.print(" (");
11934            pw.print(r.adjType);
11935            pw.println(')');
11936            if (r.adjSource != null || r.adjTarget != null) {
11937                pw.print(prefix);
11938                pw.print("    ");
11939                if (r.adjTarget instanceof ComponentName) {
11940                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11941                } else if (r.adjTarget != null) {
11942                    pw.print(r.adjTarget.toString());
11943                } else {
11944                    pw.print("{null}");
11945                }
11946                pw.print("<=");
11947                if (r.adjSource instanceof ProcessRecord) {
11948                    pw.print("Proc{");
11949                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11950                    pw.println("}");
11951                } else if (r.adjSource != null) {
11952                    pw.println(r.adjSource.toString());
11953                } else {
11954                    pw.println("{null}");
11955                }
11956            }
11957            if (inclDetails) {
11958                pw.print(prefix);
11959                pw.print("    ");
11960                pw.print("oom: max="); pw.print(r.maxAdj);
11961                pw.print(" curRaw="); pw.print(r.curRawAdj);
11962                pw.print(" setRaw="); pw.print(r.setRawAdj);
11963                pw.print(" cur="); pw.print(r.curAdj);
11964                pw.print(" set="); pw.println(r.setAdj);
11965                pw.print(prefix);
11966                pw.print("    ");
11967                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11968                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11969                pw.print(" lastPss="); pw.print(r.lastPss);
11970                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11971                pw.print(prefix);
11972                pw.print("    ");
11973                pw.print("keeping="); pw.print(r.keeping);
11974                pw.print(" cached="); pw.print(r.cached);
11975                pw.print(" empty="); pw.print(r.empty);
11976                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11977
11978                if (!r.keeping) {
11979                    if (r.lastWakeTime != 0) {
11980                        long wtime;
11981                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11982                        synchronized (stats) {
11983                            wtime = stats.getProcessWakeTime(r.info.uid,
11984                                    r.pid, curRealtime);
11985                        }
11986                        long timeUsed = wtime - r.lastWakeTime;
11987                        pw.print(prefix);
11988                        pw.print("    ");
11989                        pw.print("keep awake over ");
11990                        TimeUtils.formatDuration(realtimeSince, pw);
11991                        pw.print(" used ");
11992                        TimeUtils.formatDuration(timeUsed, pw);
11993                        pw.print(" (");
11994                        pw.print((timeUsed*100)/realtimeSince);
11995                        pw.println("%)");
11996                    }
11997                    if (r.lastCpuTime != 0) {
11998                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11999                        pw.print(prefix);
12000                        pw.print("    ");
12001                        pw.print("run cpu over ");
12002                        TimeUtils.formatDuration(uptimeSince, pw);
12003                        pw.print(" used ");
12004                        TimeUtils.formatDuration(timeUsed, pw);
12005                        pw.print(" (");
12006                        pw.print((timeUsed*100)/uptimeSince);
12007                        pw.println("%)");
12008                    }
12009                }
12010            }
12011        }
12012        return true;
12013    }
12014
12015    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12016        ArrayList<ProcessRecord> procs;
12017        synchronized (this) {
12018            if (args != null && args.length > start
12019                    && args[start].charAt(0) != '-') {
12020                procs = new ArrayList<ProcessRecord>();
12021                int pid = -1;
12022                try {
12023                    pid = Integer.parseInt(args[start]);
12024                } catch (NumberFormatException e) {
12025                }
12026                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12027                    ProcessRecord proc = mLruProcesses.get(i);
12028                    if (proc.pid == pid) {
12029                        procs.add(proc);
12030                    } else if (proc.processName.equals(args[start])) {
12031                        procs.add(proc);
12032                    }
12033                }
12034                if (procs.size() <= 0) {
12035                    return null;
12036                }
12037            } else {
12038                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12039            }
12040        }
12041        return procs;
12042    }
12043
12044    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12045            PrintWriter pw, String[] args) {
12046        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12047        if (procs == null) {
12048            pw.println("No process found for: " + args[0]);
12049            return;
12050        }
12051
12052        long uptime = SystemClock.uptimeMillis();
12053        long realtime = SystemClock.elapsedRealtime();
12054        pw.println("Applications Graphics Acceleration Info:");
12055        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12056
12057        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12058            ProcessRecord r = procs.get(i);
12059            if (r.thread != null) {
12060                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12061                pw.flush();
12062                try {
12063                    TransferPipe tp = new TransferPipe();
12064                    try {
12065                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12066                        tp.go(fd);
12067                    } finally {
12068                        tp.kill();
12069                    }
12070                } catch (IOException e) {
12071                    pw.println("Failure while dumping the app: " + r);
12072                    pw.flush();
12073                } catch (RemoteException e) {
12074                    pw.println("Got a RemoteException while dumping the app " + r);
12075                    pw.flush();
12076                }
12077            }
12078        }
12079    }
12080
12081    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12082        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12083        if (procs == null) {
12084            pw.println("No process found for: " + args[0]);
12085            return;
12086        }
12087
12088        pw.println("Applications Database Info:");
12089
12090        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12091            ProcessRecord r = procs.get(i);
12092            if (r.thread != null) {
12093                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12094                pw.flush();
12095                try {
12096                    TransferPipe tp = new TransferPipe();
12097                    try {
12098                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12099                        tp.go(fd);
12100                    } finally {
12101                        tp.kill();
12102                    }
12103                } catch (IOException e) {
12104                    pw.println("Failure while dumping the app: " + r);
12105                    pw.flush();
12106                } catch (RemoteException e) {
12107                    pw.println("Got a RemoteException while dumping the app " + r);
12108                    pw.flush();
12109                }
12110            }
12111        }
12112    }
12113
12114    final static class MemItem {
12115        final boolean isProc;
12116        final String label;
12117        final String shortLabel;
12118        final long pss;
12119        final int id;
12120        final boolean hasActivities;
12121        ArrayList<MemItem> subitems;
12122
12123        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12124                boolean _hasActivities) {
12125            isProc = true;
12126            label = _label;
12127            shortLabel = _shortLabel;
12128            pss = _pss;
12129            id = _id;
12130            hasActivities = _hasActivities;
12131        }
12132
12133        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12134            isProc = false;
12135            label = _label;
12136            shortLabel = _shortLabel;
12137            pss = _pss;
12138            id = _id;
12139            hasActivities = false;
12140        }
12141    }
12142
12143    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12144            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12145        if (sort && !isCompact) {
12146            Collections.sort(items, new Comparator<MemItem>() {
12147                @Override
12148                public int compare(MemItem lhs, MemItem rhs) {
12149                    if (lhs.pss < rhs.pss) {
12150                        return 1;
12151                    } else if (lhs.pss > rhs.pss) {
12152                        return -1;
12153                    }
12154                    return 0;
12155                }
12156            });
12157        }
12158
12159        for (int i=0; i<items.size(); i++) {
12160            MemItem mi = items.get(i);
12161            if (!isCompact) {
12162                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12163            } else if (mi.isProc) {
12164                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12165                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12166                pw.println(mi.hasActivities ? ",a" : ",e");
12167            } else {
12168                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12169                pw.println(mi.pss);
12170            }
12171            if (mi.subitems != null) {
12172                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12173                        true, isCompact);
12174            }
12175        }
12176    }
12177
12178    // These are in KB.
12179    static final long[] DUMP_MEM_BUCKETS = new long[] {
12180        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12181        120*1024, 160*1024, 200*1024,
12182        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12183        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12184    };
12185
12186    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12187            boolean stackLike) {
12188        int start = label.lastIndexOf('.');
12189        if (start >= 0) start++;
12190        else start = 0;
12191        int end = label.length();
12192        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12193            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12194                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12195                out.append(bucket);
12196                out.append(stackLike ? "MB." : "MB ");
12197                out.append(label, start, end);
12198                return;
12199            }
12200        }
12201        out.append(memKB/1024);
12202        out.append(stackLike ? "MB." : "MB ");
12203        out.append(label, start, end);
12204    }
12205
12206    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12207            ProcessList.NATIVE_ADJ,
12208            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12209            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12210            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12211            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12212            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12213    };
12214    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12215            "Native",
12216            "System", "Persistent", "Foreground",
12217            "Visible", "Perceptible",
12218            "Heavy Weight", "Backup",
12219            "A Services", "Home",
12220            "Previous", "B Services", "Cached"
12221    };
12222    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12223            "native",
12224            "sys", "pers", "fore",
12225            "vis", "percept",
12226            "heavy", "backup",
12227            "servicea", "home",
12228            "prev", "serviceb", "cached"
12229    };
12230
12231    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12232            long realtime, boolean isCheckinRequest, boolean isCompact) {
12233        if (isCheckinRequest || isCompact) {
12234            // short checkin version
12235            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12236        } else {
12237            pw.println("Applications Memory Usage (kB):");
12238            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12239        }
12240    }
12241
12242    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12243            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12244        boolean dumpDetails = false;
12245        boolean dumpFullDetails = false;
12246        boolean dumpDalvik = false;
12247        boolean oomOnly = false;
12248        boolean isCompact = false;
12249        boolean localOnly = false;
12250
12251        int opti = 0;
12252        while (opti < args.length) {
12253            String opt = args[opti];
12254            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12255                break;
12256            }
12257            opti++;
12258            if ("-a".equals(opt)) {
12259                dumpDetails = true;
12260                dumpFullDetails = true;
12261                dumpDalvik = true;
12262            } else if ("-d".equals(opt)) {
12263                dumpDalvik = true;
12264            } else if ("-c".equals(opt)) {
12265                isCompact = true;
12266            } else if ("--oom".equals(opt)) {
12267                oomOnly = true;
12268            } else if ("--local".equals(opt)) {
12269                localOnly = true;
12270            } else if ("-h".equals(opt)) {
12271                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12272                pw.println("  -a: include all available information for each process.");
12273                pw.println("  -d: include dalvik details when dumping process details.");
12274                pw.println("  -c: dump in a compact machine-parseable representation.");
12275                pw.println("  --oom: only show processes organized by oom adj.");
12276                pw.println("  --local: only collect details locally, don't call process.");
12277                pw.println("If [process] is specified it can be the name or ");
12278                pw.println("pid of a specific process to dump.");
12279                return;
12280            } else {
12281                pw.println("Unknown argument: " + opt + "; use -h for help");
12282            }
12283        }
12284
12285        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12286        long uptime = SystemClock.uptimeMillis();
12287        long realtime = SystemClock.elapsedRealtime();
12288        final long[] tmpLong = new long[1];
12289
12290        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12291        if (procs == null) {
12292            // No Java processes.  Maybe they want to print a native process.
12293            if (args != null && args.length > opti
12294                    && args[opti].charAt(0) != '-') {
12295                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12296                        = new ArrayList<ProcessCpuTracker.Stats>();
12297                updateCpuStatsNow();
12298                int findPid = -1;
12299                try {
12300                    findPid = Integer.parseInt(args[opti]);
12301                } catch (NumberFormatException e) {
12302                }
12303                synchronized (mProcessCpuThread) {
12304                    final int N = mProcessCpuTracker.countStats();
12305                    for (int i=0; i<N; i++) {
12306                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12307                        if (st.pid == findPid || (st.baseName != null
12308                                && st.baseName.equals(args[opti]))) {
12309                            nativeProcs.add(st);
12310                        }
12311                    }
12312                }
12313                if (nativeProcs.size() > 0) {
12314                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12315                            isCompact);
12316                    Debug.MemoryInfo mi = null;
12317                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12318                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12319                        final int pid = r.pid;
12320                        if (!isCheckinRequest && dumpDetails) {
12321                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12322                        }
12323                        if (mi == null) {
12324                            mi = new Debug.MemoryInfo();
12325                        }
12326                        if (dumpDetails || (!brief && !oomOnly)) {
12327                            Debug.getMemoryInfo(pid, mi);
12328                        } else {
12329                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12330                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12331                        }
12332                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12333                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12334                        if (isCheckinRequest) {
12335                            pw.println();
12336                        }
12337                    }
12338                    return;
12339                }
12340            }
12341            pw.println("No process found for: " + args[opti]);
12342            return;
12343        }
12344
12345        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12346            dumpDetails = true;
12347        }
12348
12349        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12350
12351        String[] innerArgs = new String[args.length-opti];
12352        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12353
12354        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12355        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12356        long nativePss=0, dalvikPss=0, otherPss=0;
12357        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12358
12359        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12360        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12361                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12362
12363        long totalPss = 0;
12364        long cachedPss = 0;
12365
12366        Debug.MemoryInfo mi = null;
12367        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12368            final ProcessRecord r = procs.get(i);
12369            final IApplicationThread thread;
12370            final int pid;
12371            final int oomAdj;
12372            final boolean hasActivities;
12373            synchronized (this) {
12374                thread = r.thread;
12375                pid = r.pid;
12376                oomAdj = r.getSetAdjWithServices();
12377                hasActivities = r.activities.size() > 0;
12378            }
12379            if (thread != null) {
12380                if (!isCheckinRequest && dumpDetails) {
12381                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
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                if (dumpDetails) {
12393                    if (localOnly) {
12394                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12395                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12396                        if (isCheckinRequest) {
12397                            pw.println();
12398                        }
12399                    } else {
12400                        try {
12401                            pw.flush();
12402                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12403                                    dumpDalvik, innerArgs);
12404                        } catch (RemoteException e) {
12405                            if (!isCheckinRequest) {
12406                                pw.println("Got RemoteException!");
12407                                pw.flush();
12408                            }
12409                        }
12410                    }
12411                }
12412
12413                final long myTotalPss = mi.getTotalPss();
12414                final long myTotalUss = mi.getTotalUss();
12415
12416                synchronized (this) {
12417                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12418                        // Record this for posterity if the process has been stable.
12419                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12420                    }
12421                }
12422
12423                if (!isCheckinRequest && mi != null) {
12424                    totalPss += myTotalPss;
12425                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12426                            (hasActivities ? " / activities)" : ")"),
12427                            r.processName, myTotalPss, pid, hasActivities);
12428                    procMems.add(pssItem);
12429                    procMemsMap.put(pid, pssItem);
12430
12431                    nativePss += mi.nativePss;
12432                    dalvikPss += mi.dalvikPss;
12433                    otherPss += mi.otherPss;
12434                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12435                        long mem = mi.getOtherPss(j);
12436                        miscPss[j] += mem;
12437                        otherPss -= mem;
12438                    }
12439
12440                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12441                        cachedPss += myTotalPss;
12442                    }
12443
12444                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12445                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12446                                || oomIndex == (oomPss.length-1)) {
12447                            oomPss[oomIndex] += myTotalPss;
12448                            if (oomProcs[oomIndex] == null) {
12449                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12450                            }
12451                            oomProcs[oomIndex].add(pssItem);
12452                            break;
12453                        }
12454                    }
12455                }
12456            }
12457        }
12458
12459        if (!isCheckinRequest && procs.size() > 1) {
12460            // If we are showing aggregations, also look for native processes to
12461            // include so that our aggregations are more accurate.
12462            updateCpuStatsNow();
12463            synchronized (mProcessCpuThread) {
12464                final int N = mProcessCpuTracker.countStats();
12465                for (int i=0; i<N; i++) {
12466                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12467                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12468                        if (mi == null) {
12469                            mi = new Debug.MemoryInfo();
12470                        }
12471                        if (!brief && !oomOnly) {
12472                            Debug.getMemoryInfo(st.pid, mi);
12473                        } else {
12474                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12475                            mi.nativePrivateDirty = (int)tmpLong[0];
12476                        }
12477
12478                        final long myTotalPss = mi.getTotalPss();
12479                        totalPss += myTotalPss;
12480
12481                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12482                                st.name, myTotalPss, st.pid, false);
12483                        procMems.add(pssItem);
12484
12485                        nativePss += mi.nativePss;
12486                        dalvikPss += mi.dalvikPss;
12487                        otherPss += mi.otherPss;
12488                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12489                            long mem = mi.getOtherPss(j);
12490                            miscPss[j] += mem;
12491                            otherPss -= mem;
12492                        }
12493                        oomPss[0] += myTotalPss;
12494                        if (oomProcs[0] == null) {
12495                            oomProcs[0] = new ArrayList<MemItem>();
12496                        }
12497                        oomProcs[0].add(pssItem);
12498                    }
12499                }
12500            }
12501
12502            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12503
12504            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12505            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12506            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12507            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12508                String label = Debug.MemoryInfo.getOtherLabel(j);
12509                catMems.add(new MemItem(label, label, miscPss[j], j));
12510            }
12511
12512            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12513            for (int j=0; j<oomPss.length; j++) {
12514                if (oomPss[j] != 0) {
12515                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12516                            : DUMP_MEM_OOM_LABEL[j];
12517                    MemItem item = new MemItem(label, label, oomPss[j],
12518                            DUMP_MEM_OOM_ADJ[j]);
12519                    item.subitems = oomProcs[j];
12520                    oomMems.add(item);
12521                }
12522            }
12523
12524            if (!brief && !oomOnly && !isCompact) {
12525                pw.println();
12526                pw.println("Total PSS by process:");
12527                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12528                pw.println();
12529            }
12530            if (!isCompact) {
12531                pw.println("Total PSS by OOM adjustment:");
12532            }
12533            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12534            if (!brief && !oomOnly) {
12535                PrintWriter out = categoryPw != null ? categoryPw : pw;
12536                if (!isCompact) {
12537                    out.println();
12538                    out.println("Total PSS by category:");
12539                }
12540                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12541            }
12542            if (!isCompact) {
12543                pw.println();
12544            }
12545            MemInfoReader memInfo = new MemInfoReader();
12546            memInfo.readMemInfo();
12547            if (!brief) {
12548                if (!isCompact) {
12549                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12550                    pw.print(" kB (status ");
12551                    switch (mLastMemoryLevel) {
12552                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12553                            pw.println("normal)");
12554                            break;
12555                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12556                            pw.println("moderate)");
12557                            break;
12558                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12559                            pw.println("low)");
12560                            break;
12561                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12562                            pw.println("critical)");
12563                            break;
12564                        default:
12565                            pw.print(mLastMemoryLevel);
12566                            pw.println(")");
12567                            break;
12568                    }
12569                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12570                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12571                            pw.print(cachedPss); pw.print(" cached pss + ");
12572                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12573                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12574                } else {
12575                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12576                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12577                            + memInfo.getFreeSizeKb()); pw.print(",");
12578                    pw.println(totalPss - cachedPss);
12579                }
12580            }
12581            if (!isCompact) {
12582                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12583                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12584                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12585                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12586                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12587                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12588                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12589                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12590                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12591                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12592                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12593            }
12594            if (!brief) {
12595                if (memInfo.getZramTotalSizeKb() != 0) {
12596                    if (!isCompact) {
12597                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12598                                pw.print(" kB physical used for ");
12599                                pw.print(memInfo.getSwapTotalSizeKb()
12600                                        - memInfo.getSwapFreeSizeKb());
12601                                pw.print(" kB in swap (");
12602                                pw.print(memInfo.getSwapTotalSizeKb());
12603                                pw.println(" kB total swap)");
12604                    } else {
12605                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12606                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12607                                pw.println(memInfo.getSwapFreeSizeKb());
12608                    }
12609                }
12610                final int[] SINGLE_LONG_FORMAT = new int[] {
12611                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12612                };
12613                long[] longOut = new long[1];
12614                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12615                        SINGLE_LONG_FORMAT, null, longOut, null);
12616                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12617                longOut[0] = 0;
12618                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12619                        SINGLE_LONG_FORMAT, null, longOut, null);
12620                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12621                longOut[0] = 0;
12622                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12623                        SINGLE_LONG_FORMAT, null, longOut, null);
12624                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12625                longOut[0] = 0;
12626                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12627                        SINGLE_LONG_FORMAT, null, longOut, null);
12628                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12629                if (!isCompact) {
12630                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12631                        pw.print("      KSM: "); pw.print(sharing);
12632                                pw.print(" kB saved from shared ");
12633                                pw.print(shared); pw.println(" kB");
12634                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12635                                pw.print(voltile); pw.println(" kB volatile");
12636                    }
12637                    pw.print("   Tuning: ");
12638                    pw.print(ActivityManager.staticGetMemoryClass());
12639                    pw.print(" (large ");
12640                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12641                    pw.print("), oom ");
12642                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12643                    pw.print(" kB");
12644                    pw.print(", restore limit ");
12645                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12646                    pw.print(" kB");
12647                    if (ActivityManager.isLowRamDeviceStatic()) {
12648                        pw.print(" (low-ram)");
12649                    }
12650                    if (ActivityManager.isHighEndGfx()) {
12651                        pw.print(" (high-end-gfx)");
12652                    }
12653                    pw.println();
12654                } else {
12655                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12656                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12657                    pw.println(voltile);
12658                    pw.print("tuning,");
12659                    pw.print(ActivityManager.staticGetMemoryClass());
12660                    pw.print(',');
12661                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12662                    pw.print(',');
12663                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12664                    if (ActivityManager.isLowRamDeviceStatic()) {
12665                        pw.print(",low-ram");
12666                    }
12667                    if (ActivityManager.isHighEndGfx()) {
12668                        pw.print(",high-end-gfx");
12669                    }
12670                    pw.println();
12671                }
12672            }
12673        }
12674    }
12675
12676    /**
12677     * Searches array of arguments for the specified string
12678     * @param args array of argument strings
12679     * @param value value to search for
12680     * @return true if the value is contained in the array
12681     */
12682    private static boolean scanArgs(String[] args, String value) {
12683        if (args != null) {
12684            for (String arg : args) {
12685                if (value.equals(arg)) {
12686                    return true;
12687                }
12688            }
12689        }
12690        return false;
12691    }
12692
12693    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12694            ContentProviderRecord cpr, boolean always) {
12695        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12696
12697        if (!inLaunching || always) {
12698            synchronized (cpr) {
12699                cpr.launchingApp = null;
12700                cpr.notifyAll();
12701            }
12702            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12703            String names[] = cpr.info.authority.split(";");
12704            for (int j = 0; j < names.length; j++) {
12705                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12706            }
12707        }
12708
12709        for (int i=0; i<cpr.connections.size(); i++) {
12710            ContentProviderConnection conn = cpr.connections.get(i);
12711            if (conn.waiting) {
12712                // If this connection is waiting for the provider, then we don't
12713                // need to mess with its process unless we are always removing
12714                // or for some reason the provider is not currently launching.
12715                if (inLaunching && !always) {
12716                    continue;
12717                }
12718            }
12719            ProcessRecord capp = conn.client;
12720            conn.dead = true;
12721            if (conn.stableCount > 0) {
12722                if (!capp.persistent && capp.thread != null
12723                        && capp.pid != 0
12724                        && capp.pid != MY_PID) {
12725                    killUnneededProcessLocked(capp, "depends on provider "
12726                            + cpr.name.flattenToShortString()
12727                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12728                }
12729            } else if (capp.thread != null && conn.provider.provider != null) {
12730                try {
12731                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12732                } catch (RemoteException e) {
12733                }
12734                // In the protocol here, we don't expect the client to correctly
12735                // clean up this connection, we'll just remove it.
12736                cpr.connections.remove(i);
12737                conn.client.conProviders.remove(conn);
12738            }
12739        }
12740
12741        if (inLaunching && always) {
12742            mLaunchingProviders.remove(cpr);
12743        }
12744        return inLaunching;
12745    }
12746
12747    /**
12748     * Main code for cleaning up a process when it has gone away.  This is
12749     * called both as a result of the process dying, or directly when stopping
12750     * a process when running in single process mode.
12751     */
12752    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12753            boolean restarting, boolean allowRestart, int index) {
12754        if (index >= 0) {
12755            removeLruProcessLocked(app);
12756            ProcessList.remove(app.pid);
12757        }
12758
12759        mProcessesToGc.remove(app);
12760        mPendingPssProcesses.remove(app);
12761
12762        // Dismiss any open dialogs.
12763        if (app.crashDialog != null && !app.forceCrashReport) {
12764            app.crashDialog.dismiss();
12765            app.crashDialog = null;
12766        }
12767        if (app.anrDialog != null) {
12768            app.anrDialog.dismiss();
12769            app.anrDialog = null;
12770        }
12771        if (app.waitDialog != null) {
12772            app.waitDialog.dismiss();
12773            app.waitDialog = null;
12774        }
12775
12776        app.crashing = false;
12777        app.notResponding = false;
12778
12779        app.resetPackageList(mProcessStats);
12780        app.unlinkDeathRecipient();
12781        app.makeInactive(mProcessStats);
12782        app.forcingToForeground = null;
12783        updateProcessForegroundLocked(app, false, false);
12784        app.foregroundActivities = false;
12785        app.hasShownUi = false;
12786        app.treatLikeActivity = false;
12787        app.hasAboveClient = false;
12788        app.hasClientActivities = false;
12789
12790        mServices.killServicesLocked(app, allowRestart);
12791
12792        boolean restart = false;
12793
12794        // Remove published content providers.
12795        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12796            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12797            final boolean always = app.bad || !allowRestart;
12798            if (removeDyingProviderLocked(app, cpr, always) || always) {
12799                // We left the provider in the launching list, need to
12800                // restart it.
12801                restart = true;
12802            }
12803
12804            cpr.provider = null;
12805            cpr.proc = null;
12806        }
12807        app.pubProviders.clear();
12808
12809        // Take care of any launching providers waiting for this process.
12810        if (checkAppInLaunchingProvidersLocked(app, false)) {
12811            restart = true;
12812        }
12813
12814        // Unregister from connected content providers.
12815        if (!app.conProviders.isEmpty()) {
12816            for (int i=0; i<app.conProviders.size(); i++) {
12817                ContentProviderConnection conn = app.conProviders.get(i);
12818                conn.provider.connections.remove(conn);
12819            }
12820            app.conProviders.clear();
12821        }
12822
12823        // At this point there may be remaining entries in mLaunchingProviders
12824        // where we were the only one waiting, so they are no longer of use.
12825        // Look for these and clean up if found.
12826        // XXX Commented out for now.  Trying to figure out a way to reproduce
12827        // the actual situation to identify what is actually going on.
12828        if (false) {
12829            for (int i=0; i<mLaunchingProviders.size(); i++) {
12830                ContentProviderRecord cpr = (ContentProviderRecord)
12831                        mLaunchingProviders.get(i);
12832                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12833                    synchronized (cpr) {
12834                        cpr.launchingApp = null;
12835                        cpr.notifyAll();
12836                    }
12837                }
12838            }
12839        }
12840
12841        skipCurrentReceiverLocked(app);
12842
12843        // Unregister any receivers.
12844        for (int i=app.receivers.size()-1; i>=0; i--) {
12845            removeReceiverLocked(app.receivers.valueAt(i));
12846        }
12847        app.receivers.clear();
12848
12849        // If the app is undergoing backup, tell the backup manager about it
12850        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12851            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12852                    + mBackupTarget.appInfo + " died during backup");
12853            try {
12854                IBackupManager bm = IBackupManager.Stub.asInterface(
12855                        ServiceManager.getService(Context.BACKUP_SERVICE));
12856                bm.agentDisconnected(app.info.packageName);
12857            } catch (RemoteException e) {
12858                // can't happen; backup manager is local
12859            }
12860        }
12861
12862        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12863            ProcessChangeItem item = mPendingProcessChanges.get(i);
12864            if (item.pid == app.pid) {
12865                mPendingProcessChanges.remove(i);
12866                mAvailProcessChanges.add(item);
12867            }
12868        }
12869        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12870
12871        // If the caller is restarting this app, then leave it in its
12872        // current lists and let the caller take care of it.
12873        if (restarting) {
12874            return;
12875        }
12876
12877        if (!app.persistent || app.isolated) {
12878            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12879                    "Removing non-persistent process during cleanup: " + app);
12880            mProcessNames.remove(app.processName, app.uid);
12881            mIsolatedProcesses.remove(app.uid);
12882            if (mHeavyWeightProcess == app) {
12883                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12884                        mHeavyWeightProcess.userId, 0));
12885                mHeavyWeightProcess = null;
12886            }
12887        } else if (!app.removed) {
12888            // This app is persistent, so we need to keep its record around.
12889            // If it is not already on the pending app list, add it there
12890            // and start a new process for it.
12891            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12892                mPersistentStartingProcesses.add(app);
12893                restart = true;
12894            }
12895        }
12896        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12897                "Clean-up removing on hold: " + app);
12898        mProcessesOnHold.remove(app);
12899
12900        if (app == mHomeProcess) {
12901            mHomeProcess = null;
12902        }
12903        if (app == mPreviousProcess) {
12904            mPreviousProcess = null;
12905        }
12906
12907        if (restart && !app.isolated) {
12908            // We have components that still need to be running in the
12909            // process, so re-launch it.
12910            mProcessNames.put(app.processName, app.uid, app);
12911            startProcessLocked(app, "restart", app.processName);
12912        } else if (app.pid > 0 && app.pid != MY_PID) {
12913            // Goodbye!
12914            boolean removed;
12915            synchronized (mPidsSelfLocked) {
12916                mPidsSelfLocked.remove(app.pid);
12917                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12918            }
12919            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12920                    app.processName, app.info.uid);
12921            if (app.isolated) {
12922                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12923            }
12924            app.setPid(0);
12925        }
12926    }
12927
12928    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12929        // Look through the content providers we are waiting to have launched,
12930        // and if any run in this process then either schedule a restart of
12931        // the process or kill the client waiting for it if this process has
12932        // gone bad.
12933        int NL = mLaunchingProviders.size();
12934        boolean restart = false;
12935        for (int i=0; i<NL; i++) {
12936            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12937            if (cpr.launchingApp == app) {
12938                if (!alwaysBad && !app.bad) {
12939                    restart = true;
12940                } else {
12941                    removeDyingProviderLocked(app, cpr, true);
12942                    // cpr should have been removed from mLaunchingProviders
12943                    NL = mLaunchingProviders.size();
12944                    i--;
12945                }
12946            }
12947        }
12948        return restart;
12949    }
12950
12951    // =========================================================
12952    // SERVICES
12953    // =========================================================
12954
12955    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12956            int flags) {
12957        enforceNotIsolatedCaller("getServices");
12958        synchronized (this) {
12959            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12960        }
12961    }
12962
12963    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12964        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12965        synchronized (this) {
12966            return mServices.getRunningServiceControlPanelLocked(name);
12967        }
12968    }
12969
12970    public ComponentName startService(IApplicationThread caller, Intent service,
12971            String resolvedType, int userId) {
12972        enforceNotIsolatedCaller("startService");
12973        // Refuse possible leaked file descriptors
12974        if (service != null && service.hasFileDescriptors() == true) {
12975            throw new IllegalArgumentException("File descriptors passed in Intent");
12976        }
12977
12978        if (DEBUG_SERVICE)
12979            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12980        synchronized(this) {
12981            final int callingPid = Binder.getCallingPid();
12982            final int callingUid = Binder.getCallingUid();
12983            final long origId = Binder.clearCallingIdentity();
12984            ComponentName res = mServices.startServiceLocked(caller, service,
12985                    resolvedType, callingPid, callingUid, userId);
12986            Binder.restoreCallingIdentity(origId);
12987            return res;
12988        }
12989    }
12990
12991    ComponentName startServiceInPackage(int uid,
12992            Intent service, String resolvedType, int userId) {
12993        synchronized(this) {
12994            if (DEBUG_SERVICE)
12995                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12996            final long origId = Binder.clearCallingIdentity();
12997            ComponentName res = mServices.startServiceLocked(null, service,
12998                    resolvedType, -1, uid, userId);
12999            Binder.restoreCallingIdentity(origId);
13000            return res;
13001        }
13002    }
13003
13004    public int stopService(IApplicationThread caller, Intent service,
13005            String resolvedType, int userId) {
13006        enforceNotIsolatedCaller("stopService");
13007        // Refuse possible leaked file descriptors
13008        if (service != null && service.hasFileDescriptors() == true) {
13009            throw new IllegalArgumentException("File descriptors passed in Intent");
13010        }
13011
13012        synchronized(this) {
13013            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13014        }
13015    }
13016
13017    public IBinder peekService(Intent service, String resolvedType) {
13018        enforceNotIsolatedCaller("peekService");
13019        // Refuse possible leaked file descriptors
13020        if (service != null && service.hasFileDescriptors() == true) {
13021            throw new IllegalArgumentException("File descriptors passed in Intent");
13022        }
13023        synchronized(this) {
13024            return mServices.peekServiceLocked(service, resolvedType);
13025        }
13026    }
13027
13028    public boolean stopServiceToken(ComponentName className, IBinder token,
13029            int startId) {
13030        synchronized(this) {
13031            return mServices.stopServiceTokenLocked(className, token, startId);
13032        }
13033    }
13034
13035    public void setServiceForeground(ComponentName className, IBinder token,
13036            int id, Notification notification, boolean removeNotification) {
13037        synchronized(this) {
13038            mServices.setServiceForegroundLocked(className, token, id, notification,
13039                    removeNotification);
13040        }
13041    }
13042
13043    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13044            boolean requireFull, String name, String callerPackage) {
13045        final int callingUserId = UserHandle.getUserId(callingUid);
13046        if (callingUserId != userId) {
13047            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13048                if ((requireFull || checkComponentPermission(
13049                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13050                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13051                        && checkComponentPermission(
13052                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13053                                callingPid, callingUid, -1, true)
13054                                != PackageManager.PERMISSION_GRANTED) {
13055                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13056                        // In this case, they would like to just execute as their
13057                        // owner user instead of failing.
13058                        userId = callingUserId;
13059                    } else {
13060                        StringBuilder builder = new StringBuilder(128);
13061                        builder.append("Permission Denial: ");
13062                        builder.append(name);
13063                        if (callerPackage != null) {
13064                            builder.append(" from ");
13065                            builder.append(callerPackage);
13066                        }
13067                        builder.append(" asks to run as user ");
13068                        builder.append(userId);
13069                        builder.append(" but is calling from user ");
13070                        builder.append(UserHandle.getUserId(callingUid));
13071                        builder.append("; this requires ");
13072                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13073                        if (!requireFull) {
13074                            builder.append(" or ");
13075                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13076                        }
13077                        String msg = builder.toString();
13078                        Slog.w(TAG, msg);
13079                        throw new SecurityException(msg);
13080                    }
13081                }
13082            }
13083            if (userId == UserHandle.USER_CURRENT
13084                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13085                // Note that we may be accessing this outside of a lock...
13086                // shouldn't be a big deal, if this is being called outside
13087                // of a locked context there is intrinsically a race with
13088                // the value the caller will receive and someone else changing it.
13089                userId = mCurrentUserId;
13090            }
13091            if (!allowAll && userId < 0) {
13092                throw new IllegalArgumentException(
13093                        "Call does not support special user #" + userId);
13094            }
13095        }
13096        return userId;
13097    }
13098
13099    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13100            String className, int flags) {
13101        boolean result = false;
13102        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13103            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13104                if (ActivityManager.checkUidPermission(
13105                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13106                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13107                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13108                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13109                            + " requests FLAG_SINGLE_USER, but app does not hold "
13110                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13111                    Slog.w(TAG, msg);
13112                    throw new SecurityException(msg);
13113                }
13114                result = true;
13115            }
13116        } else if (componentProcessName == aInfo.packageName) {
13117            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13118        } else if ("system".equals(componentProcessName)) {
13119            result = true;
13120        }
13121        if (DEBUG_MU) {
13122            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13123                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13124        }
13125        return result;
13126    }
13127
13128    public int bindService(IApplicationThread caller, IBinder token,
13129            Intent service, String resolvedType,
13130            IServiceConnection connection, int flags, int userId) {
13131        enforceNotIsolatedCaller("bindService");
13132        // Refuse possible leaked file descriptors
13133        if (service != null && service.hasFileDescriptors() == true) {
13134            throw new IllegalArgumentException("File descriptors passed in Intent");
13135        }
13136
13137        synchronized(this) {
13138            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13139                    connection, flags, userId);
13140        }
13141    }
13142
13143    public boolean unbindService(IServiceConnection connection) {
13144        synchronized (this) {
13145            return mServices.unbindServiceLocked(connection);
13146        }
13147    }
13148
13149    public void publishService(IBinder token, Intent intent, IBinder service) {
13150        // Refuse possible leaked file descriptors
13151        if (intent != null && intent.hasFileDescriptors() == true) {
13152            throw new IllegalArgumentException("File descriptors passed in Intent");
13153        }
13154
13155        synchronized(this) {
13156            if (!(token instanceof ServiceRecord)) {
13157                throw new IllegalArgumentException("Invalid service token");
13158            }
13159            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13160        }
13161    }
13162
13163    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13164        // Refuse possible leaked file descriptors
13165        if (intent != null && intent.hasFileDescriptors() == true) {
13166            throw new IllegalArgumentException("File descriptors passed in Intent");
13167        }
13168
13169        synchronized(this) {
13170            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13171        }
13172    }
13173
13174    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13175        synchronized(this) {
13176            if (!(token instanceof ServiceRecord)) {
13177                throw new IllegalArgumentException("Invalid service token");
13178            }
13179            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13180        }
13181    }
13182
13183    // =========================================================
13184    // BACKUP AND RESTORE
13185    // =========================================================
13186
13187    // Cause the target app to be launched if necessary and its backup agent
13188    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13189    // activity manager to announce its creation.
13190    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13191        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13192        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13193
13194        synchronized(this) {
13195            // !!! TODO: currently no check here that we're already bound
13196            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13197            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13198            synchronized (stats) {
13199                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13200            }
13201
13202            // Backup agent is now in use, its package can't be stopped.
13203            try {
13204                AppGlobals.getPackageManager().setPackageStoppedState(
13205                        app.packageName, false, UserHandle.getUserId(app.uid));
13206            } catch (RemoteException e) {
13207            } catch (IllegalArgumentException e) {
13208                Slog.w(TAG, "Failed trying to unstop package "
13209                        + app.packageName + ": " + e);
13210            }
13211
13212            BackupRecord r = new BackupRecord(ss, app, backupMode);
13213            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13214                    ? new ComponentName(app.packageName, app.backupAgentName)
13215                    : new ComponentName("android", "FullBackupAgent");
13216            // startProcessLocked() returns existing proc's record if it's already running
13217            ProcessRecord proc = startProcessLocked(app.processName, app,
13218                    false, 0, "backup", hostingName, false, false, false);
13219            if (proc == null) {
13220                Slog.e(TAG, "Unable to start backup agent process " + r);
13221                return false;
13222            }
13223
13224            r.app = proc;
13225            mBackupTarget = r;
13226            mBackupAppName = app.packageName;
13227
13228            // Try not to kill the process during backup
13229            updateOomAdjLocked(proc);
13230
13231            // If the process is already attached, schedule the creation of the backup agent now.
13232            // If it is not yet live, this will be done when it attaches to the framework.
13233            if (proc.thread != null) {
13234                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13235                try {
13236                    proc.thread.scheduleCreateBackupAgent(app,
13237                            compatibilityInfoForPackageLocked(app), backupMode);
13238                } catch (RemoteException e) {
13239                    // Will time out on the backup manager side
13240                }
13241            } else {
13242                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13243            }
13244            // Invariants: at this point, the target app process exists and the application
13245            // is either already running or in the process of coming up.  mBackupTarget and
13246            // mBackupAppName describe the app, so that when it binds back to the AM we
13247            // know that it's scheduled for a backup-agent operation.
13248        }
13249
13250        return true;
13251    }
13252
13253    @Override
13254    public void clearPendingBackup() {
13255        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13256        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13257
13258        synchronized (this) {
13259            mBackupTarget = null;
13260            mBackupAppName = null;
13261        }
13262    }
13263
13264    // A backup agent has just come up
13265    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13266        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13267                + " = " + agent);
13268
13269        synchronized(this) {
13270            if (!agentPackageName.equals(mBackupAppName)) {
13271                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13272                return;
13273            }
13274        }
13275
13276        long oldIdent = Binder.clearCallingIdentity();
13277        try {
13278            IBackupManager bm = IBackupManager.Stub.asInterface(
13279                    ServiceManager.getService(Context.BACKUP_SERVICE));
13280            bm.agentConnected(agentPackageName, agent);
13281        } catch (RemoteException e) {
13282            // can't happen; the backup manager service is local
13283        } catch (Exception e) {
13284            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13285            e.printStackTrace();
13286        } finally {
13287            Binder.restoreCallingIdentity(oldIdent);
13288        }
13289    }
13290
13291    // done with this agent
13292    public void unbindBackupAgent(ApplicationInfo appInfo) {
13293        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13294        if (appInfo == null) {
13295            Slog.w(TAG, "unbind backup agent for null app");
13296            return;
13297        }
13298
13299        synchronized(this) {
13300            try {
13301                if (mBackupAppName == null) {
13302                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13303                    return;
13304                }
13305
13306                if (!mBackupAppName.equals(appInfo.packageName)) {
13307                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13308                    return;
13309                }
13310
13311                // Not backing this app up any more; reset its OOM adjustment
13312                final ProcessRecord proc = mBackupTarget.app;
13313                updateOomAdjLocked(proc);
13314
13315                // If the app crashed during backup, 'thread' will be null here
13316                if (proc.thread != null) {
13317                    try {
13318                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13319                                compatibilityInfoForPackageLocked(appInfo));
13320                    } catch (Exception e) {
13321                        Slog.e(TAG, "Exception when unbinding backup agent:");
13322                        e.printStackTrace();
13323                    }
13324                }
13325            } finally {
13326                mBackupTarget = null;
13327                mBackupAppName = null;
13328            }
13329        }
13330    }
13331    // =========================================================
13332    // BROADCASTS
13333    // =========================================================
13334
13335    private final List getStickiesLocked(String action, IntentFilter filter,
13336            List cur, int userId) {
13337        final ContentResolver resolver = mContext.getContentResolver();
13338        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13339        if (stickies == null) {
13340            return cur;
13341        }
13342        final ArrayList<Intent> list = stickies.get(action);
13343        if (list == null) {
13344            return cur;
13345        }
13346        int N = list.size();
13347        for (int i=0; i<N; i++) {
13348            Intent intent = list.get(i);
13349            if (filter.match(resolver, intent, true, TAG) >= 0) {
13350                if (cur == null) {
13351                    cur = new ArrayList<Intent>();
13352                }
13353                cur.add(intent);
13354            }
13355        }
13356        return cur;
13357    }
13358
13359    boolean isPendingBroadcastProcessLocked(int pid) {
13360        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13361                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13362    }
13363
13364    void skipPendingBroadcastLocked(int pid) {
13365            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13366            for (BroadcastQueue queue : mBroadcastQueues) {
13367                queue.skipPendingBroadcastLocked(pid);
13368            }
13369    }
13370
13371    // The app just attached; send any pending broadcasts that it should receive
13372    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13373        boolean didSomething = false;
13374        for (BroadcastQueue queue : mBroadcastQueues) {
13375            didSomething |= queue.sendPendingBroadcastsLocked(app);
13376        }
13377        return didSomething;
13378    }
13379
13380    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13381            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13382        enforceNotIsolatedCaller("registerReceiver");
13383        int callingUid;
13384        int callingPid;
13385        synchronized(this) {
13386            ProcessRecord callerApp = null;
13387            if (caller != null) {
13388                callerApp = getRecordForAppLocked(caller);
13389                if (callerApp == null) {
13390                    throw new SecurityException(
13391                            "Unable to find app for caller " + caller
13392                            + " (pid=" + Binder.getCallingPid()
13393                            + ") when registering receiver " + receiver);
13394                }
13395                if (callerApp.info.uid != Process.SYSTEM_UID &&
13396                        !callerApp.pkgList.containsKey(callerPackage) &&
13397                        !"android".equals(callerPackage)) {
13398                    throw new SecurityException("Given caller package " + callerPackage
13399                            + " is not running in process " + callerApp);
13400                }
13401                callingUid = callerApp.info.uid;
13402                callingPid = callerApp.pid;
13403            } else {
13404                callerPackage = null;
13405                callingUid = Binder.getCallingUid();
13406                callingPid = Binder.getCallingPid();
13407            }
13408
13409            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13410                    true, true, "registerReceiver", callerPackage);
13411
13412            List allSticky = null;
13413
13414            // Look for any matching sticky broadcasts...
13415            Iterator actions = filter.actionsIterator();
13416            if (actions != null) {
13417                while (actions.hasNext()) {
13418                    String action = (String)actions.next();
13419                    allSticky = getStickiesLocked(action, filter, allSticky,
13420                            UserHandle.USER_ALL);
13421                    allSticky = getStickiesLocked(action, filter, allSticky,
13422                            UserHandle.getUserId(callingUid));
13423                }
13424            } else {
13425                allSticky = getStickiesLocked(null, filter, allSticky,
13426                        UserHandle.USER_ALL);
13427                allSticky = getStickiesLocked(null, filter, allSticky,
13428                        UserHandle.getUserId(callingUid));
13429            }
13430
13431            // The first sticky in the list is returned directly back to
13432            // the client.
13433            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13434
13435            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13436                    + ": " + sticky);
13437
13438            if (receiver == null) {
13439                return sticky;
13440            }
13441
13442            ReceiverList rl
13443                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13444            if (rl == null) {
13445                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13446                        userId, receiver);
13447                if (rl.app != null) {
13448                    rl.app.receivers.add(rl);
13449                } else {
13450                    try {
13451                        receiver.asBinder().linkToDeath(rl, 0);
13452                    } catch (RemoteException e) {
13453                        return sticky;
13454                    }
13455                    rl.linkedToDeath = true;
13456                }
13457                mRegisteredReceivers.put(receiver.asBinder(), rl);
13458            } else if (rl.uid != callingUid) {
13459                throw new IllegalArgumentException(
13460                        "Receiver requested to register for uid " + callingUid
13461                        + " was previously registered for uid " + rl.uid);
13462            } else if (rl.pid != callingPid) {
13463                throw new IllegalArgumentException(
13464                        "Receiver requested to register for pid " + callingPid
13465                        + " was previously registered for pid " + rl.pid);
13466            } else if (rl.userId != userId) {
13467                throw new IllegalArgumentException(
13468                        "Receiver requested to register for user " + userId
13469                        + " was previously registered for user " + rl.userId);
13470            }
13471            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13472                    permission, callingUid, userId);
13473            rl.add(bf);
13474            if (!bf.debugCheck()) {
13475                Slog.w(TAG, "==> For Dynamic broadast");
13476            }
13477            mReceiverResolver.addFilter(bf);
13478
13479            // Enqueue broadcasts for all existing stickies that match
13480            // this filter.
13481            if (allSticky != null) {
13482                ArrayList receivers = new ArrayList();
13483                receivers.add(bf);
13484
13485                int N = allSticky.size();
13486                for (int i=0; i<N; i++) {
13487                    Intent intent = (Intent)allSticky.get(i);
13488                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13489                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13490                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13491                            null, null, false, true, true, -1);
13492                    queue.enqueueParallelBroadcastLocked(r);
13493                    queue.scheduleBroadcastsLocked();
13494                }
13495            }
13496
13497            return sticky;
13498        }
13499    }
13500
13501    public void unregisterReceiver(IIntentReceiver receiver) {
13502        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13503
13504        final long origId = Binder.clearCallingIdentity();
13505        try {
13506            boolean doTrim = false;
13507
13508            synchronized(this) {
13509                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13510                if (rl != null) {
13511                    if (rl.curBroadcast != null) {
13512                        BroadcastRecord r = rl.curBroadcast;
13513                        final boolean doNext = finishReceiverLocked(
13514                                receiver.asBinder(), r.resultCode, r.resultData,
13515                                r.resultExtras, r.resultAbort);
13516                        if (doNext) {
13517                            doTrim = true;
13518                            r.queue.processNextBroadcast(false);
13519                        }
13520                    }
13521
13522                    if (rl.app != null) {
13523                        rl.app.receivers.remove(rl);
13524                    }
13525                    removeReceiverLocked(rl);
13526                    if (rl.linkedToDeath) {
13527                        rl.linkedToDeath = false;
13528                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13529                    }
13530                }
13531            }
13532
13533            // If we actually concluded any broadcasts, we might now be able
13534            // to trim the recipients' apps from our working set
13535            if (doTrim) {
13536                trimApplications();
13537                return;
13538            }
13539
13540        } finally {
13541            Binder.restoreCallingIdentity(origId);
13542        }
13543    }
13544
13545    void removeReceiverLocked(ReceiverList rl) {
13546        mRegisteredReceivers.remove(rl.receiver.asBinder());
13547        int N = rl.size();
13548        for (int i=0; i<N; i++) {
13549            mReceiverResolver.removeFilter(rl.get(i));
13550        }
13551    }
13552
13553    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13554        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13555            ProcessRecord r = mLruProcesses.get(i);
13556            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13557                try {
13558                    r.thread.dispatchPackageBroadcast(cmd, packages);
13559                } catch (RemoteException ex) {
13560                }
13561            }
13562        }
13563    }
13564
13565    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13566            int[] users) {
13567        List<ResolveInfo> receivers = null;
13568        try {
13569            HashSet<ComponentName> singleUserReceivers = null;
13570            boolean scannedFirstReceivers = false;
13571            for (int user : users) {
13572                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13573                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13574                if (user != 0 && newReceivers != null) {
13575                    // If this is not the primary user, we need to check for
13576                    // any receivers that should be filtered out.
13577                    for (int i=0; i<newReceivers.size(); i++) {
13578                        ResolveInfo ri = newReceivers.get(i);
13579                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13580                            newReceivers.remove(i);
13581                            i--;
13582                        }
13583                    }
13584                }
13585                if (newReceivers != null && newReceivers.size() == 0) {
13586                    newReceivers = null;
13587                }
13588                if (receivers == null) {
13589                    receivers = newReceivers;
13590                } else if (newReceivers != null) {
13591                    // We need to concatenate the additional receivers
13592                    // found with what we have do far.  This would be easy,
13593                    // but we also need to de-dup any receivers that are
13594                    // singleUser.
13595                    if (!scannedFirstReceivers) {
13596                        // Collect any single user receivers we had already retrieved.
13597                        scannedFirstReceivers = true;
13598                        for (int i=0; i<receivers.size(); i++) {
13599                            ResolveInfo ri = receivers.get(i);
13600                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13601                                ComponentName cn = new ComponentName(
13602                                        ri.activityInfo.packageName, ri.activityInfo.name);
13603                                if (singleUserReceivers == null) {
13604                                    singleUserReceivers = new HashSet<ComponentName>();
13605                                }
13606                                singleUserReceivers.add(cn);
13607                            }
13608                        }
13609                    }
13610                    // Add the new results to the existing results, tracking
13611                    // and de-dupping single user receivers.
13612                    for (int i=0; i<newReceivers.size(); i++) {
13613                        ResolveInfo ri = newReceivers.get(i);
13614                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13615                            ComponentName cn = new ComponentName(
13616                                    ri.activityInfo.packageName, ri.activityInfo.name);
13617                            if (singleUserReceivers == null) {
13618                                singleUserReceivers = new HashSet<ComponentName>();
13619                            }
13620                            if (!singleUserReceivers.contains(cn)) {
13621                                singleUserReceivers.add(cn);
13622                                receivers.add(ri);
13623                            }
13624                        } else {
13625                            receivers.add(ri);
13626                        }
13627                    }
13628                }
13629            }
13630        } catch (RemoteException ex) {
13631            // pm is in same process, this will never happen.
13632        }
13633        return receivers;
13634    }
13635
13636    private final int broadcastIntentLocked(ProcessRecord callerApp,
13637            String callerPackage, Intent intent, String resolvedType,
13638            IIntentReceiver resultTo, int resultCode, String resultData,
13639            Bundle map, String requiredPermission, int appOp,
13640            boolean ordered, boolean sticky, int callingPid, int callingUid,
13641            int userId) {
13642        intent = new Intent(intent);
13643
13644        // By default broadcasts do not go to stopped apps.
13645        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13646
13647        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13648            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13649            + " ordered=" + ordered + " userid=" + userId);
13650        if ((resultTo != null) && !ordered) {
13651            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13652        }
13653
13654        userId = handleIncomingUser(callingPid, callingUid, userId,
13655                true, false, "broadcast", callerPackage);
13656
13657        // Make sure that the user who is receiving this broadcast is started.
13658        // If not, we will just skip it.
13659        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13660            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13661                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13662                Slog.w(TAG, "Skipping broadcast of " + intent
13663                        + ": user " + userId + " is stopped");
13664                return ActivityManager.BROADCAST_SUCCESS;
13665            }
13666        }
13667
13668        /*
13669         * Prevent non-system code (defined here to be non-persistent
13670         * processes) from sending protected broadcasts.
13671         */
13672        int callingAppId = UserHandle.getAppId(callingUid);
13673        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13674            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13675            callingUid == 0) {
13676            // Always okay.
13677        } else if (callerApp == null || !callerApp.persistent) {
13678            try {
13679                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13680                        intent.getAction())) {
13681                    String msg = "Permission Denial: not allowed to send broadcast "
13682                            + intent.getAction() + " from pid="
13683                            + callingPid + ", uid=" + callingUid;
13684                    Slog.w(TAG, msg);
13685                    throw new SecurityException(msg);
13686                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13687                    // Special case for compatibility: we don't want apps to send this,
13688                    // but historically it has not been protected and apps may be using it
13689                    // to poke their own app widget.  So, instead of making it protected,
13690                    // just limit it to the caller.
13691                    if (callerApp == null) {
13692                        String msg = "Permission Denial: not allowed to send broadcast "
13693                                + intent.getAction() + " from unknown caller.";
13694                        Slog.w(TAG, msg);
13695                        throw new SecurityException(msg);
13696                    } else if (intent.getComponent() != null) {
13697                        // They are good enough to send to an explicit component...  verify
13698                        // it is being sent to the calling app.
13699                        if (!intent.getComponent().getPackageName().equals(
13700                                callerApp.info.packageName)) {
13701                            String msg = "Permission Denial: not allowed to send broadcast "
13702                                    + intent.getAction() + " to "
13703                                    + intent.getComponent().getPackageName() + " from "
13704                                    + callerApp.info.packageName;
13705                            Slog.w(TAG, msg);
13706                            throw new SecurityException(msg);
13707                        }
13708                    } else {
13709                        // Limit broadcast to their own package.
13710                        intent.setPackage(callerApp.info.packageName);
13711                    }
13712                }
13713            } catch (RemoteException e) {
13714                Slog.w(TAG, "Remote exception", e);
13715                return ActivityManager.BROADCAST_SUCCESS;
13716            }
13717        }
13718
13719        // Handle special intents: if this broadcast is from the package
13720        // manager about a package being removed, we need to remove all of
13721        // its activities from the history stack.
13722        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13723                intent.getAction());
13724        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13725                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13726                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13727                || uidRemoved) {
13728            if (checkComponentPermission(
13729                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13730                    callingPid, callingUid, -1, true)
13731                    == PackageManager.PERMISSION_GRANTED) {
13732                if (uidRemoved) {
13733                    final Bundle intentExtras = intent.getExtras();
13734                    final int uid = intentExtras != null
13735                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13736                    if (uid >= 0) {
13737                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13738                        synchronized (bs) {
13739                            bs.removeUidStatsLocked(uid);
13740                        }
13741                        mAppOpsService.uidRemoved(uid);
13742                    }
13743                } else {
13744                    // If resources are unavailable just force stop all
13745                    // those packages and flush the attribute cache as well.
13746                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13747                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13748                        if (list != null && (list.length > 0)) {
13749                            for (String pkg : list) {
13750                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13751                                        "storage unmount");
13752                            }
13753                            sendPackageBroadcastLocked(
13754                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13755                        }
13756                    } else {
13757                        Uri data = intent.getData();
13758                        String ssp;
13759                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13760                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13761                                    intent.getAction());
13762                            boolean fullUninstall = removed &&
13763                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13764                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13765                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13766                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13767                                        false, fullUninstall, userId,
13768                                        removed ? "pkg removed" : "pkg changed");
13769                            }
13770                            if (removed) {
13771                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13772                                        new String[] {ssp}, userId);
13773                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13774                                    mAppOpsService.packageRemoved(
13775                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13776
13777                                    // Remove all permissions granted from/to this package
13778                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13779                                }
13780                            }
13781                        }
13782                    }
13783                }
13784            } else {
13785                String msg = "Permission Denial: " + intent.getAction()
13786                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13787                        + ", uid=" + callingUid + ")"
13788                        + " requires "
13789                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13790                Slog.w(TAG, msg);
13791                throw new SecurityException(msg);
13792            }
13793
13794        // Special case for adding a package: by default turn on compatibility
13795        // mode.
13796        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13797            Uri data = intent.getData();
13798            String ssp;
13799            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13800                mCompatModePackages.handlePackageAddedLocked(ssp,
13801                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13802            }
13803        }
13804
13805        /*
13806         * If this is the time zone changed action, queue up a message that will reset the timezone
13807         * of all currently running processes. This message will get queued up before the broadcast
13808         * happens.
13809         */
13810        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13811            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13812        }
13813
13814        /*
13815         * If the user set the time, let all running processes know.
13816         */
13817        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13818            final int is24Hour = intent.getBooleanExtra(
13819                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13820            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13821        }
13822
13823        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13824            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13825        }
13826
13827        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13828            ProxyInfo proxy = intent.getParcelableExtra("proxy");
13829            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13830        }
13831
13832        // Add to the sticky list if requested.
13833        if (sticky) {
13834            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13835                    callingPid, callingUid)
13836                    != PackageManager.PERMISSION_GRANTED) {
13837                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13838                        + callingPid + ", uid=" + callingUid
13839                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13840                Slog.w(TAG, msg);
13841                throw new SecurityException(msg);
13842            }
13843            if (requiredPermission != null) {
13844                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13845                        + " and enforce permission " + requiredPermission);
13846                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13847            }
13848            if (intent.getComponent() != null) {
13849                throw new SecurityException(
13850                        "Sticky broadcasts can't target a specific component");
13851            }
13852            // We use userId directly here, since the "all" target is maintained
13853            // as a separate set of sticky broadcasts.
13854            if (userId != UserHandle.USER_ALL) {
13855                // But first, if this is not a broadcast to all users, then
13856                // make sure it doesn't conflict with an existing broadcast to
13857                // all users.
13858                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13859                        UserHandle.USER_ALL);
13860                if (stickies != null) {
13861                    ArrayList<Intent> list = stickies.get(intent.getAction());
13862                    if (list != null) {
13863                        int N = list.size();
13864                        int i;
13865                        for (i=0; i<N; i++) {
13866                            if (intent.filterEquals(list.get(i))) {
13867                                throw new IllegalArgumentException(
13868                                        "Sticky broadcast " + intent + " for user "
13869                                        + userId + " conflicts with existing global broadcast");
13870                            }
13871                        }
13872                    }
13873                }
13874            }
13875            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13876            if (stickies == null) {
13877                stickies = new ArrayMap<String, ArrayList<Intent>>();
13878                mStickyBroadcasts.put(userId, stickies);
13879            }
13880            ArrayList<Intent> list = stickies.get(intent.getAction());
13881            if (list == null) {
13882                list = new ArrayList<Intent>();
13883                stickies.put(intent.getAction(), list);
13884            }
13885            int N = list.size();
13886            int i;
13887            for (i=0; i<N; i++) {
13888                if (intent.filterEquals(list.get(i))) {
13889                    // This sticky already exists, replace it.
13890                    list.set(i, new Intent(intent));
13891                    break;
13892                }
13893            }
13894            if (i >= N) {
13895                list.add(new Intent(intent));
13896            }
13897        }
13898
13899        int[] users;
13900        if (userId == UserHandle.USER_ALL) {
13901            // Caller wants broadcast to go to all started users.
13902            users = mStartedUserArray;
13903        } else {
13904            // Caller wants broadcast to go to one specific user.
13905            users = new int[] {userId};
13906        }
13907
13908        // Figure out who all will receive this broadcast.
13909        List receivers = null;
13910        List<BroadcastFilter> registeredReceivers = null;
13911        // Need to resolve the intent to interested receivers...
13912        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13913                 == 0) {
13914            receivers = collectReceiverComponents(intent, resolvedType, users);
13915        }
13916        if (intent.getComponent() == null) {
13917            registeredReceivers = mReceiverResolver.queryIntent(intent,
13918                    resolvedType, false, userId);
13919        }
13920
13921        final boolean replacePending =
13922                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13923
13924        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13925                + " replacePending=" + replacePending);
13926
13927        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13928        if (!ordered && NR > 0) {
13929            // If we are not serializing this broadcast, then send the
13930            // registered receivers separately so they don't wait for the
13931            // components to be launched.
13932            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13933            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13934                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13935                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13936                    ordered, sticky, false, userId);
13937            if (DEBUG_BROADCAST) Slog.v(
13938                    TAG, "Enqueueing parallel broadcast " + r);
13939            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13940            if (!replaced) {
13941                queue.enqueueParallelBroadcastLocked(r);
13942                queue.scheduleBroadcastsLocked();
13943            }
13944            registeredReceivers = null;
13945            NR = 0;
13946        }
13947
13948        // Merge into one list.
13949        int ir = 0;
13950        if (receivers != null) {
13951            // A special case for PACKAGE_ADDED: do not allow the package
13952            // being added to see this broadcast.  This prevents them from
13953            // using this as a back door to get run as soon as they are
13954            // installed.  Maybe in the future we want to have a special install
13955            // broadcast or such for apps, but we'd like to deliberately make
13956            // this decision.
13957            String skipPackages[] = null;
13958            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13959                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13960                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13961                Uri data = intent.getData();
13962                if (data != null) {
13963                    String pkgName = data.getSchemeSpecificPart();
13964                    if (pkgName != null) {
13965                        skipPackages = new String[] { pkgName };
13966                    }
13967                }
13968            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13969                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13970            }
13971            if (skipPackages != null && (skipPackages.length > 0)) {
13972                for (String skipPackage : skipPackages) {
13973                    if (skipPackage != null) {
13974                        int NT = receivers.size();
13975                        for (int it=0; it<NT; it++) {
13976                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13977                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13978                                receivers.remove(it);
13979                                it--;
13980                                NT--;
13981                            }
13982                        }
13983                    }
13984                }
13985            }
13986
13987            int NT = receivers != null ? receivers.size() : 0;
13988            int it = 0;
13989            ResolveInfo curt = null;
13990            BroadcastFilter curr = null;
13991            while (it < NT && ir < NR) {
13992                if (curt == null) {
13993                    curt = (ResolveInfo)receivers.get(it);
13994                }
13995                if (curr == null) {
13996                    curr = registeredReceivers.get(ir);
13997                }
13998                if (curr.getPriority() >= curt.priority) {
13999                    // Insert this broadcast record into the final list.
14000                    receivers.add(it, curr);
14001                    ir++;
14002                    curr = null;
14003                    it++;
14004                    NT++;
14005                } else {
14006                    // Skip to the next ResolveInfo in the final list.
14007                    it++;
14008                    curt = null;
14009                }
14010            }
14011        }
14012        while (ir < NR) {
14013            if (receivers == null) {
14014                receivers = new ArrayList();
14015            }
14016            receivers.add(registeredReceivers.get(ir));
14017            ir++;
14018        }
14019
14020        if ((receivers != null && receivers.size() > 0)
14021                || resultTo != null) {
14022            BroadcastQueue queue = broadcastQueueForIntent(intent);
14023            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14024                    callerPackage, callingPid, callingUid, resolvedType,
14025                    requiredPermission, appOp, receivers, resultTo, resultCode,
14026                    resultData, map, ordered, sticky, false, userId);
14027            if (DEBUG_BROADCAST) Slog.v(
14028                    TAG, "Enqueueing ordered broadcast " + r
14029                    + ": prev had " + queue.mOrderedBroadcasts.size());
14030            if (DEBUG_BROADCAST) {
14031                int seq = r.intent.getIntExtra("seq", -1);
14032                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14033            }
14034            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14035            if (!replaced) {
14036                queue.enqueueOrderedBroadcastLocked(r);
14037                queue.scheduleBroadcastsLocked();
14038            }
14039        }
14040
14041        return ActivityManager.BROADCAST_SUCCESS;
14042    }
14043
14044    final Intent verifyBroadcastLocked(Intent intent) {
14045        // Refuse possible leaked file descriptors
14046        if (intent != null && intent.hasFileDescriptors() == true) {
14047            throw new IllegalArgumentException("File descriptors passed in Intent");
14048        }
14049
14050        int flags = intent.getFlags();
14051
14052        if (!mProcessesReady) {
14053            // if the caller really truly claims to know what they're doing, go
14054            // ahead and allow the broadcast without launching any receivers
14055            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14056                intent = new Intent(intent);
14057                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14058            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14059                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14060                        + " before boot completion");
14061                throw new IllegalStateException("Cannot broadcast before boot completed");
14062            }
14063        }
14064
14065        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14066            throw new IllegalArgumentException(
14067                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14068        }
14069
14070        return intent;
14071    }
14072
14073    public final int broadcastIntent(IApplicationThread caller,
14074            Intent intent, String resolvedType, IIntentReceiver resultTo,
14075            int resultCode, String resultData, Bundle map,
14076            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14077        enforceNotIsolatedCaller("broadcastIntent");
14078        synchronized(this) {
14079            intent = verifyBroadcastLocked(intent);
14080
14081            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14082            final int callingPid = Binder.getCallingPid();
14083            final int callingUid = Binder.getCallingUid();
14084            final long origId = Binder.clearCallingIdentity();
14085            int res = broadcastIntentLocked(callerApp,
14086                    callerApp != null ? callerApp.info.packageName : null,
14087                    intent, resolvedType, resultTo,
14088                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14089                    callingPid, callingUid, userId);
14090            Binder.restoreCallingIdentity(origId);
14091            return res;
14092        }
14093    }
14094
14095    int broadcastIntentInPackage(String packageName, int uid,
14096            Intent intent, String resolvedType, IIntentReceiver resultTo,
14097            int resultCode, String resultData, Bundle map,
14098            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14099        synchronized(this) {
14100            intent = verifyBroadcastLocked(intent);
14101
14102            final long origId = Binder.clearCallingIdentity();
14103            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14104                    resultTo, resultCode, resultData, map, requiredPermission,
14105                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14106            Binder.restoreCallingIdentity(origId);
14107            return res;
14108        }
14109    }
14110
14111    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14112        // Refuse possible leaked file descriptors
14113        if (intent != null && intent.hasFileDescriptors() == true) {
14114            throw new IllegalArgumentException("File descriptors passed in Intent");
14115        }
14116
14117        userId = handleIncomingUser(Binder.getCallingPid(),
14118                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14119
14120        synchronized(this) {
14121            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14122                    != PackageManager.PERMISSION_GRANTED) {
14123                String msg = "Permission Denial: unbroadcastIntent() from pid="
14124                        + Binder.getCallingPid()
14125                        + ", uid=" + Binder.getCallingUid()
14126                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14127                Slog.w(TAG, msg);
14128                throw new SecurityException(msg);
14129            }
14130            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14131            if (stickies != null) {
14132                ArrayList<Intent> list = stickies.get(intent.getAction());
14133                if (list != null) {
14134                    int N = list.size();
14135                    int i;
14136                    for (i=0; i<N; i++) {
14137                        if (intent.filterEquals(list.get(i))) {
14138                            list.remove(i);
14139                            break;
14140                        }
14141                    }
14142                    if (list.size() <= 0) {
14143                        stickies.remove(intent.getAction());
14144                    }
14145                }
14146                if (stickies.size() <= 0) {
14147                    mStickyBroadcasts.remove(userId);
14148                }
14149            }
14150        }
14151    }
14152
14153    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14154            String resultData, Bundle resultExtras, boolean resultAbort) {
14155        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14156        if (r == null) {
14157            Slog.w(TAG, "finishReceiver called but not found on queue");
14158            return false;
14159        }
14160
14161        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14162    }
14163
14164    void backgroundServicesFinishedLocked(int userId) {
14165        for (BroadcastQueue queue : mBroadcastQueues) {
14166            queue.backgroundServicesFinishedLocked(userId);
14167        }
14168    }
14169
14170    public void finishReceiver(IBinder who, int resultCode, String resultData,
14171            Bundle resultExtras, boolean resultAbort) {
14172        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14173
14174        // Refuse possible leaked file descriptors
14175        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14176            throw new IllegalArgumentException("File descriptors passed in Bundle");
14177        }
14178
14179        final long origId = Binder.clearCallingIdentity();
14180        try {
14181            boolean doNext = false;
14182            BroadcastRecord r;
14183
14184            synchronized(this) {
14185                r = broadcastRecordForReceiverLocked(who);
14186                if (r != null) {
14187                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14188                        resultData, resultExtras, resultAbort, true);
14189                }
14190            }
14191
14192            if (doNext) {
14193                r.queue.processNextBroadcast(false);
14194            }
14195            trimApplications();
14196        } finally {
14197            Binder.restoreCallingIdentity(origId);
14198        }
14199    }
14200
14201    // =========================================================
14202    // INSTRUMENTATION
14203    // =========================================================
14204
14205    public boolean startInstrumentation(ComponentName className,
14206            String profileFile, int flags, Bundle arguments,
14207            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14208            int userId) {
14209        enforceNotIsolatedCaller("startInstrumentation");
14210        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14211                userId, false, true, "startInstrumentation", null);
14212        // Refuse possible leaked file descriptors
14213        if (arguments != null && arguments.hasFileDescriptors()) {
14214            throw new IllegalArgumentException("File descriptors passed in Bundle");
14215        }
14216
14217        synchronized(this) {
14218            InstrumentationInfo ii = null;
14219            ApplicationInfo ai = null;
14220            try {
14221                ii = mContext.getPackageManager().getInstrumentationInfo(
14222                    className, STOCK_PM_FLAGS);
14223                ai = AppGlobals.getPackageManager().getApplicationInfo(
14224                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14225            } catch (PackageManager.NameNotFoundException e) {
14226            } catch (RemoteException e) {
14227            }
14228            if (ii == null) {
14229                reportStartInstrumentationFailure(watcher, className,
14230                        "Unable to find instrumentation info for: " + className);
14231                return false;
14232            }
14233            if (ai == null) {
14234                reportStartInstrumentationFailure(watcher, className,
14235                        "Unable to find instrumentation target package: " + ii.targetPackage);
14236                return false;
14237            }
14238
14239            int match = mContext.getPackageManager().checkSignatures(
14240                    ii.targetPackage, ii.packageName);
14241            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14242                String msg = "Permission Denial: starting instrumentation "
14243                        + className + " from pid="
14244                        + Binder.getCallingPid()
14245                        + ", uid=" + Binder.getCallingPid()
14246                        + " not allowed because package " + ii.packageName
14247                        + " does not have a signature matching the target "
14248                        + ii.targetPackage;
14249                reportStartInstrumentationFailure(watcher, className, msg);
14250                throw new SecurityException(msg);
14251            }
14252
14253            final long origId = Binder.clearCallingIdentity();
14254            // Instrumentation can kill and relaunch even persistent processes
14255            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14256                    "start instr");
14257            ProcessRecord app = addAppLocked(ai, false);
14258            app.instrumentationClass = className;
14259            app.instrumentationInfo = ai;
14260            app.instrumentationProfileFile = profileFile;
14261            app.instrumentationArguments = arguments;
14262            app.instrumentationWatcher = watcher;
14263            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14264            app.instrumentationResultClass = className;
14265            Binder.restoreCallingIdentity(origId);
14266        }
14267
14268        return true;
14269    }
14270
14271    /**
14272     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14273     * error to the logs, but if somebody is watching, send the report there too.  This enables
14274     * the "am" command to report errors with more information.
14275     *
14276     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14277     * @param cn The component name of the instrumentation.
14278     * @param report The error report.
14279     */
14280    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14281            ComponentName cn, String report) {
14282        Slog.w(TAG, report);
14283        try {
14284            if (watcher != null) {
14285                Bundle results = new Bundle();
14286                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14287                results.putString("Error", report);
14288                watcher.instrumentationStatus(cn, -1, results);
14289            }
14290        } catch (RemoteException e) {
14291            Slog.w(TAG, e);
14292        }
14293    }
14294
14295    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14296        if (app.instrumentationWatcher != null) {
14297            try {
14298                // NOTE:  IInstrumentationWatcher *must* be oneway here
14299                app.instrumentationWatcher.instrumentationFinished(
14300                    app.instrumentationClass,
14301                    resultCode,
14302                    results);
14303            } catch (RemoteException e) {
14304            }
14305        }
14306        if (app.instrumentationUiAutomationConnection != null) {
14307            try {
14308                app.instrumentationUiAutomationConnection.shutdown();
14309            } catch (RemoteException re) {
14310                /* ignore */
14311            }
14312            // Only a UiAutomation can set this flag and now that
14313            // it is finished we make sure it is reset to its default.
14314            mUserIsMonkey = false;
14315        }
14316        app.instrumentationWatcher = null;
14317        app.instrumentationUiAutomationConnection = null;
14318        app.instrumentationClass = null;
14319        app.instrumentationInfo = null;
14320        app.instrumentationProfileFile = null;
14321        app.instrumentationArguments = null;
14322
14323        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14324                "finished inst");
14325    }
14326
14327    public void finishInstrumentation(IApplicationThread target,
14328            int resultCode, Bundle results) {
14329        int userId = UserHandle.getCallingUserId();
14330        // Refuse possible leaked file descriptors
14331        if (results != null && results.hasFileDescriptors()) {
14332            throw new IllegalArgumentException("File descriptors passed in Intent");
14333        }
14334
14335        synchronized(this) {
14336            ProcessRecord app = getRecordForAppLocked(target);
14337            if (app == null) {
14338                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14339                return;
14340            }
14341            final long origId = Binder.clearCallingIdentity();
14342            finishInstrumentationLocked(app, resultCode, results);
14343            Binder.restoreCallingIdentity(origId);
14344        }
14345    }
14346
14347    // =========================================================
14348    // CONFIGURATION
14349    // =========================================================
14350
14351    public ConfigurationInfo getDeviceConfigurationInfo() {
14352        ConfigurationInfo config = new ConfigurationInfo();
14353        synchronized (this) {
14354            config.reqTouchScreen = mConfiguration.touchscreen;
14355            config.reqKeyboardType = mConfiguration.keyboard;
14356            config.reqNavigation = mConfiguration.navigation;
14357            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14358                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14359                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14360            }
14361            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14362                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14363                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14364            }
14365            config.reqGlEsVersion = GL_ES_VERSION;
14366        }
14367        return config;
14368    }
14369
14370    ActivityStack getFocusedStack() {
14371        return mStackSupervisor.getFocusedStack();
14372    }
14373
14374    public Configuration getConfiguration() {
14375        Configuration ci;
14376        synchronized(this) {
14377            ci = new Configuration(mConfiguration);
14378        }
14379        return ci;
14380    }
14381
14382    public void updatePersistentConfiguration(Configuration values) {
14383        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14384                "updateConfiguration()");
14385        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14386                "updateConfiguration()");
14387        if (values == null) {
14388            throw new NullPointerException("Configuration must not be null");
14389        }
14390
14391        synchronized(this) {
14392            final long origId = Binder.clearCallingIdentity();
14393            updateConfigurationLocked(values, null, true, false);
14394            Binder.restoreCallingIdentity(origId);
14395        }
14396    }
14397
14398    public void updateConfiguration(Configuration values) {
14399        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14400                "updateConfiguration()");
14401
14402        synchronized(this) {
14403            if (values == null && mWindowManager != null) {
14404                // sentinel: fetch the current configuration from the window manager
14405                values = mWindowManager.computeNewConfiguration();
14406            }
14407
14408            if (mWindowManager != null) {
14409                mProcessList.applyDisplaySize(mWindowManager);
14410            }
14411
14412            final long origId = Binder.clearCallingIdentity();
14413            if (values != null) {
14414                Settings.System.clearConfiguration(values);
14415            }
14416            updateConfigurationLocked(values, null, false, false);
14417            Binder.restoreCallingIdentity(origId);
14418        }
14419    }
14420
14421    /**
14422     * Do either or both things: (1) change the current configuration, and (2)
14423     * make sure the given activity is running with the (now) current
14424     * configuration.  Returns true if the activity has been left running, or
14425     * false if <var>starting</var> is being destroyed to match the new
14426     * configuration.
14427     * @param persistent TODO
14428     */
14429    boolean updateConfigurationLocked(Configuration values,
14430            ActivityRecord starting, boolean persistent, boolean initLocale) {
14431        int changes = 0;
14432
14433        if (values != null) {
14434            Configuration newConfig = new Configuration(mConfiguration);
14435            changes = newConfig.updateFrom(values);
14436            if (changes != 0) {
14437                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14438                    Slog.i(TAG, "Updating configuration to: " + values);
14439                }
14440
14441                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14442
14443                if (values.locale != null && !initLocale) {
14444                    saveLocaleLocked(values.locale,
14445                                     !values.locale.equals(mConfiguration.locale),
14446                                     values.userSetLocale);
14447                }
14448
14449                mConfigurationSeq++;
14450                if (mConfigurationSeq <= 0) {
14451                    mConfigurationSeq = 1;
14452                }
14453                newConfig.seq = mConfigurationSeq;
14454                mConfiguration = newConfig;
14455                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14456                mUsageStatsService.noteStartConfig(newConfig);
14457
14458                final Configuration configCopy = new Configuration(mConfiguration);
14459
14460                // TODO: If our config changes, should we auto dismiss any currently
14461                // showing dialogs?
14462                mShowDialogs = shouldShowDialogs(newConfig);
14463
14464                AttributeCache ac = AttributeCache.instance();
14465                if (ac != null) {
14466                    ac.updateConfiguration(configCopy);
14467                }
14468
14469                // Make sure all resources in our process are updated
14470                // right now, so that anyone who is going to retrieve
14471                // resource values after we return will be sure to get
14472                // the new ones.  This is especially important during
14473                // boot, where the first config change needs to guarantee
14474                // all resources have that config before following boot
14475                // code is executed.
14476                mSystemThread.applyConfigurationToResources(configCopy);
14477
14478                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14479                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14480                    msg.obj = new Configuration(configCopy);
14481                    mHandler.sendMessage(msg);
14482                }
14483
14484                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14485                    ProcessRecord app = mLruProcesses.get(i);
14486                    try {
14487                        if (app.thread != null) {
14488                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14489                                    + app.processName + " new config " + mConfiguration);
14490                            app.thread.scheduleConfigurationChanged(configCopy);
14491                        }
14492                    } catch (Exception e) {
14493                    }
14494                }
14495                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14496                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14497                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14498                        | Intent.FLAG_RECEIVER_FOREGROUND);
14499                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14500                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14501                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14502                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14503                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14504                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14505                    broadcastIntentLocked(null, null, intent,
14506                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14507                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14508                }
14509            }
14510        }
14511
14512        boolean kept = true;
14513        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14514        // mainStack is null during startup.
14515        if (mainStack != null) {
14516            if (changes != 0 && starting == null) {
14517                // If the configuration changed, and the caller is not already
14518                // in the process of starting an activity, then find the top
14519                // activity to check if its configuration needs to change.
14520                starting = mainStack.topRunningActivityLocked(null);
14521            }
14522
14523            if (starting != null) {
14524                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14525                // And we need to make sure at this point that all other activities
14526                // are made visible with the correct configuration.
14527                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14528            }
14529        }
14530
14531        if (values != null && mWindowManager != null) {
14532            mWindowManager.setNewConfiguration(mConfiguration);
14533        }
14534
14535        return kept;
14536    }
14537
14538    /**
14539     * Decide based on the configuration whether we should shouw the ANR,
14540     * crash, etc dialogs.  The idea is that if there is no affordnace to
14541     * press the on-screen buttons, we shouldn't show the dialog.
14542     *
14543     * A thought: SystemUI might also want to get told about this, the Power
14544     * dialog / global actions also might want different behaviors.
14545     */
14546    private static final boolean shouldShowDialogs(Configuration config) {
14547        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14548                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14549    }
14550
14551    /**
14552     * Save the locale.  You must be inside a synchronized (this) block.
14553     */
14554    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14555        if(isDiff) {
14556            SystemProperties.set("user.language", l.getLanguage());
14557            SystemProperties.set("user.region", l.getCountry());
14558        }
14559
14560        if(isPersist) {
14561            SystemProperties.set("persist.sys.language", l.getLanguage());
14562            SystemProperties.set("persist.sys.country", l.getCountry());
14563            SystemProperties.set("persist.sys.localevar", l.getVariant());
14564        }
14565    }
14566
14567    @Override
14568    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14569        ActivityRecord srec = ActivityRecord.forToken(token);
14570        return srec != null && srec.task.affinity != null &&
14571                srec.task.affinity.equals(destAffinity);
14572    }
14573
14574    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14575            Intent resultData) {
14576
14577        synchronized (this) {
14578            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14579            if (stack != null) {
14580                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14581            }
14582            return false;
14583        }
14584    }
14585
14586    public int getLaunchedFromUid(IBinder activityToken) {
14587        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14588        if (srec == null) {
14589            return -1;
14590        }
14591        return srec.launchedFromUid;
14592    }
14593
14594    public String getLaunchedFromPackage(IBinder activityToken) {
14595        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14596        if (srec == null) {
14597            return null;
14598        }
14599        return srec.launchedFromPackage;
14600    }
14601
14602    // =========================================================
14603    // LIFETIME MANAGEMENT
14604    // =========================================================
14605
14606    // Returns which broadcast queue the app is the current [or imminent] receiver
14607    // on, or 'null' if the app is not an active broadcast recipient.
14608    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14609        BroadcastRecord r = app.curReceiver;
14610        if (r != null) {
14611            return r.queue;
14612        }
14613
14614        // It's not the current receiver, but it might be starting up to become one
14615        synchronized (this) {
14616            for (BroadcastQueue queue : mBroadcastQueues) {
14617                r = queue.mPendingBroadcast;
14618                if (r != null && r.curApp == app) {
14619                    // found it; report which queue it's in
14620                    return queue;
14621                }
14622            }
14623        }
14624
14625        return null;
14626    }
14627
14628    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14629            boolean doingAll, long now) {
14630        if (mAdjSeq == app.adjSeq) {
14631            // This adjustment has already been computed.
14632            return app.curRawAdj;
14633        }
14634
14635        if (app.thread == null) {
14636            app.adjSeq = mAdjSeq;
14637            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14638            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14639            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14640        }
14641
14642        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14643        app.adjSource = null;
14644        app.adjTarget = null;
14645        app.empty = false;
14646        app.cached = false;
14647
14648        final int activitiesSize = app.activities.size();
14649
14650        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14651            // The max adjustment doesn't allow this app to be anything
14652            // below foreground, so it is not worth doing work for it.
14653            app.adjType = "fixed";
14654            app.adjSeq = mAdjSeq;
14655            app.curRawAdj = app.maxAdj;
14656            app.foregroundActivities = false;
14657            app.keeping = true;
14658            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14659            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14660            // System processes can do UI, and when they do we want to have
14661            // them trim their memory after the user leaves the UI.  To
14662            // facilitate this, here we need to determine whether or not it
14663            // is currently showing UI.
14664            app.systemNoUi = true;
14665            if (app == TOP_APP) {
14666                app.systemNoUi = false;
14667            } else if (activitiesSize > 0) {
14668                for (int j = 0; j < activitiesSize; j++) {
14669                    final ActivityRecord r = app.activities.get(j);
14670                    if (r.visible) {
14671                        app.systemNoUi = false;
14672                    }
14673                }
14674            }
14675            if (!app.systemNoUi) {
14676                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14677            }
14678            return (app.curAdj=app.maxAdj);
14679        }
14680
14681        app.keeping = false;
14682        app.systemNoUi = false;
14683
14684        // Determine the importance of the process, starting with most
14685        // important to least, and assign an appropriate OOM adjustment.
14686        int adj;
14687        int schedGroup;
14688        int procState;
14689        boolean foregroundActivities = false;
14690        boolean interesting = false;
14691        BroadcastQueue queue;
14692        if (app == TOP_APP) {
14693            // The last app on the list is the foreground app.
14694            adj = ProcessList.FOREGROUND_APP_ADJ;
14695            schedGroup = Process.THREAD_GROUP_DEFAULT;
14696            app.adjType = "top-activity";
14697            foregroundActivities = true;
14698            interesting = true;
14699            procState = ActivityManager.PROCESS_STATE_TOP;
14700        } else if (app.instrumentationClass != null) {
14701            // Don't want to kill running instrumentation.
14702            adj = ProcessList.FOREGROUND_APP_ADJ;
14703            schedGroup = Process.THREAD_GROUP_DEFAULT;
14704            app.adjType = "instrumentation";
14705            interesting = true;
14706            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14707        } else if ((queue = isReceivingBroadcast(app)) != null) {
14708            // An app that is currently receiving a broadcast also
14709            // counts as being in the foreground for OOM killer purposes.
14710            // It's placed in a sched group based on the nature of the
14711            // broadcast as reflected by which queue it's active in.
14712            adj = ProcessList.FOREGROUND_APP_ADJ;
14713            schedGroup = (queue == mFgBroadcastQueue)
14714                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14715            app.adjType = "broadcast";
14716            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14717        } else if (app.executingServices.size() > 0) {
14718            // An app that is currently executing a service callback also
14719            // counts as being in the foreground.
14720            adj = ProcessList.FOREGROUND_APP_ADJ;
14721            schedGroup = app.execServicesFg ?
14722                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14723            app.adjType = "exec-service";
14724            procState = ActivityManager.PROCESS_STATE_SERVICE;
14725            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14726        } else {
14727            // As far as we know the process is empty.  We may change our mind later.
14728            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14729            // At this point we don't actually know the adjustment.  Use the cached adj
14730            // value that the caller wants us to.
14731            adj = cachedAdj;
14732            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14733            app.cached = true;
14734            app.empty = true;
14735            app.adjType = "cch-empty";
14736        }
14737
14738        // Examine all activities if not already foreground.
14739        if (!foregroundActivities && activitiesSize > 0) {
14740            for (int j = 0; j < activitiesSize; j++) {
14741                final ActivityRecord r = app.activities.get(j);
14742                if (r.app != app) {
14743                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14744                            + app + "?!?");
14745                    continue;
14746                }
14747                if (r.visible) {
14748                    // App has a visible activity; only upgrade adjustment.
14749                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14750                        adj = ProcessList.VISIBLE_APP_ADJ;
14751                        app.adjType = "visible";
14752                    }
14753                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14754                        procState = ActivityManager.PROCESS_STATE_TOP;
14755                    }
14756                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14757                    app.cached = false;
14758                    app.empty = false;
14759                    foregroundActivities = true;
14760                    break;
14761                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14762                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14763                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14764                        app.adjType = "pausing";
14765                    }
14766                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14767                        procState = ActivityManager.PROCESS_STATE_TOP;
14768                    }
14769                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14770                    app.cached = false;
14771                    app.empty = false;
14772                    foregroundActivities = true;
14773                } else if (r.state == ActivityState.STOPPING) {
14774                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14775                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14776                        app.adjType = "stopping";
14777                    }
14778                    // For the process state, we will at this point consider the
14779                    // process to be cached.  It will be cached either as an activity
14780                    // or empty depending on whether the activity is finishing.  We do
14781                    // this so that we can treat the process as cached for purposes of
14782                    // memory trimming (determing current memory level, trim command to
14783                    // send to process) since there can be an arbitrary number of stopping
14784                    // processes and they should soon all go into the cached state.
14785                    if (!r.finishing) {
14786                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14787                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14788                        }
14789                    }
14790                    app.cached = false;
14791                    app.empty = false;
14792                    foregroundActivities = true;
14793                } else {
14794                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14795                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14796                        app.adjType = "cch-act";
14797                    }
14798                }
14799            }
14800        }
14801
14802        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14803            if (app.foregroundServices) {
14804                // The user is aware of this app, so make it visible.
14805                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14806                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14807                app.cached = false;
14808                app.adjType = "fg-service";
14809                schedGroup = Process.THREAD_GROUP_DEFAULT;
14810            } else if (app.forcingToForeground != null) {
14811                // The user is aware of this app, so make it visible.
14812                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14813                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14814                app.cached = false;
14815                app.adjType = "force-fg";
14816                app.adjSource = app.forcingToForeground;
14817                schedGroup = Process.THREAD_GROUP_DEFAULT;
14818            }
14819        }
14820
14821        if (app.foregroundServices) {
14822            interesting = true;
14823        }
14824
14825        if (app == mHeavyWeightProcess) {
14826            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14827                // We don't want to kill the current heavy-weight process.
14828                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14829                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14830                app.cached = false;
14831                app.adjType = "heavy";
14832            }
14833            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14834                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14835            }
14836        }
14837
14838        if (app == mHomeProcess) {
14839            if (adj > ProcessList.HOME_APP_ADJ) {
14840                // This process is hosting what we currently consider to be the
14841                // home app, so we don't want to let it go into the background.
14842                adj = ProcessList.HOME_APP_ADJ;
14843                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14844                app.cached = false;
14845                app.adjType = "home";
14846            }
14847            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14848                procState = ActivityManager.PROCESS_STATE_HOME;
14849            }
14850        }
14851
14852        if (app == mPreviousProcess && app.activities.size() > 0) {
14853            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14854                // This was the previous process that showed UI to the user.
14855                // We want to try to keep it around more aggressively, to give
14856                // a good experience around switching between two apps.
14857                adj = ProcessList.PREVIOUS_APP_ADJ;
14858                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14859                app.cached = false;
14860                app.adjType = "previous";
14861            }
14862            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14863                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14864            }
14865        }
14866
14867        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14868                + " reason=" + app.adjType);
14869
14870        // By default, we use the computed adjustment.  It may be changed if
14871        // there are applications dependent on our services or providers, but
14872        // this gives us a baseline and makes sure we don't get into an
14873        // infinite recursion.
14874        app.adjSeq = mAdjSeq;
14875        app.curRawAdj = adj;
14876        app.hasStartedServices = false;
14877
14878        if (mBackupTarget != null && app == mBackupTarget.app) {
14879            // If possible we want to avoid killing apps while they're being backed up
14880            if (adj > ProcessList.BACKUP_APP_ADJ) {
14881                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14882                adj = ProcessList.BACKUP_APP_ADJ;
14883                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14884                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14885                }
14886                app.adjType = "backup";
14887                app.cached = false;
14888            }
14889            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14890                procState = ActivityManager.PROCESS_STATE_BACKUP;
14891            }
14892        }
14893
14894        boolean mayBeTop = false;
14895
14896        for (int is = app.services.size()-1;
14897                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14898                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14899                        || procState > ActivityManager.PROCESS_STATE_TOP);
14900                is--) {
14901            ServiceRecord s = app.services.valueAt(is);
14902            if (s.startRequested) {
14903                app.hasStartedServices = true;
14904                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14905                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14906                }
14907                if (app.hasShownUi && app != mHomeProcess) {
14908                    // If this process has shown some UI, let it immediately
14909                    // go to the LRU list because it may be pretty heavy with
14910                    // UI stuff.  We'll tag it with a label just to help
14911                    // debug and understand what is going on.
14912                    if (adj > ProcessList.SERVICE_ADJ) {
14913                        app.adjType = "cch-started-ui-services";
14914                    }
14915                } else {
14916                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14917                        // This service has seen some activity within
14918                        // recent memory, so we will keep its process ahead
14919                        // of the background processes.
14920                        if (adj > ProcessList.SERVICE_ADJ) {
14921                            adj = ProcessList.SERVICE_ADJ;
14922                            app.adjType = "started-services";
14923                            app.cached = false;
14924                        }
14925                    }
14926                    // If we have let the service slide into the background
14927                    // state, still have some text describing what it is doing
14928                    // even though the service no longer has an impact.
14929                    if (adj > ProcessList.SERVICE_ADJ) {
14930                        app.adjType = "cch-started-services";
14931                    }
14932                }
14933                // Don't kill this process because it is doing work; it
14934                // has said it is doing work.
14935                app.keeping = true;
14936            }
14937            for (int conni = s.connections.size()-1;
14938                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14939                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14940                            || procState > ActivityManager.PROCESS_STATE_TOP);
14941                    conni--) {
14942                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14943                for (int i = 0;
14944                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14945                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14946                                || procState > ActivityManager.PROCESS_STATE_TOP);
14947                        i++) {
14948                    // XXX should compute this based on the max of
14949                    // all connected clients.
14950                    ConnectionRecord cr = clist.get(i);
14951                    if (cr.binding.client == app) {
14952                        // Binding to ourself is not interesting.
14953                        continue;
14954                    }
14955                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14956                        ProcessRecord client = cr.binding.client;
14957                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14958                                TOP_APP, doingAll, now);
14959                        int clientProcState = client.curProcState;
14960                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14961                            // If the other app is cached for any reason, for purposes here
14962                            // we are going to consider it empty.  The specific cached state
14963                            // doesn't propagate except under certain conditions.
14964                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14965                        }
14966                        String adjType = null;
14967                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14968                            // Not doing bind OOM management, so treat
14969                            // this guy more like a started service.
14970                            if (app.hasShownUi && app != mHomeProcess) {
14971                                // If this process has shown some UI, let it immediately
14972                                // go to the LRU list because it may be pretty heavy with
14973                                // UI stuff.  We'll tag it with a label just to help
14974                                // debug and understand what is going on.
14975                                if (adj > clientAdj) {
14976                                    adjType = "cch-bound-ui-services";
14977                                }
14978                                app.cached = false;
14979                                clientAdj = adj;
14980                                clientProcState = procState;
14981                            } else {
14982                                if (now >= (s.lastActivity
14983                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14984                                    // This service has not seen activity within
14985                                    // recent memory, so allow it to drop to the
14986                                    // LRU list if there is no other reason to keep
14987                                    // it around.  We'll also tag it with a label just
14988                                    // to help debug and undertand what is going on.
14989                                    if (adj > clientAdj) {
14990                                        adjType = "cch-bound-services";
14991                                    }
14992                                    clientAdj = adj;
14993                                }
14994                            }
14995                        }
14996                        if (adj > clientAdj) {
14997                            // If this process has recently shown UI, and
14998                            // the process that is binding to it is less
14999                            // important than being visible, then we don't
15000                            // care about the binding as much as we care
15001                            // about letting this process get into the LRU
15002                            // list to be killed and restarted if needed for
15003                            // memory.
15004                            if (app.hasShownUi && app != mHomeProcess
15005                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15006                                adjType = "cch-bound-ui-services";
15007                            } else {
15008                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15009                                        |Context.BIND_IMPORTANT)) != 0) {
15010                                    adj = clientAdj;
15011                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15012                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15013                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15014                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15015                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15016                                    adj = clientAdj;
15017                                } else {
15018                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15019                                        adj = ProcessList.VISIBLE_APP_ADJ;
15020                                    }
15021                                }
15022                                if (!client.cached) {
15023                                    app.cached = false;
15024                                }
15025                                if (client.keeping) {
15026                                    app.keeping = true;
15027                                }
15028                                adjType = "service";
15029                            }
15030                        }
15031                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15032                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15033                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15034                            }
15035                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15036                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15037                                    // Special handling of clients who are in the top state.
15038                                    // We *may* want to consider this process to be in the
15039                                    // top state as well, but only if there is not another
15040                                    // reason for it to be running.  Being on the top is a
15041                                    // special state, meaning you are specifically running
15042                                    // for the current top app.  If the process is already
15043                                    // running in the background for some other reason, it
15044                                    // is more important to continue considering it to be
15045                                    // in the background state.
15046                                    mayBeTop = true;
15047                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15048                                } else {
15049                                    // Special handling for above-top states (persistent
15050                                    // processes).  These should not bring the current process
15051                                    // into the top state, since they are not on top.  Instead
15052                                    // give them the best state after that.
15053                                    clientProcState =
15054                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15055                                }
15056                            }
15057                        } else {
15058                            if (clientProcState <
15059                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15060                                clientProcState =
15061                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15062                            }
15063                        }
15064                        if (procState > clientProcState) {
15065                            procState = clientProcState;
15066                        }
15067                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15068                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15069                            app.pendingUiClean = true;
15070                        }
15071                        if (adjType != null) {
15072                            app.adjType = adjType;
15073                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15074                                    .REASON_SERVICE_IN_USE;
15075                            app.adjSource = cr.binding.client;
15076                            app.adjSourceOom = clientAdj;
15077                            app.adjTarget = s.name;
15078                        }
15079                    }
15080                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15081                        app.treatLikeActivity = true;
15082                    }
15083                    final ActivityRecord a = cr.activity;
15084                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15085                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15086                                (a.visible || a.state == ActivityState.RESUMED
15087                                 || a.state == ActivityState.PAUSING)) {
15088                            adj = ProcessList.FOREGROUND_APP_ADJ;
15089                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15090                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15091                            }
15092                            app.cached = false;
15093                            app.adjType = "service";
15094                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15095                                    .REASON_SERVICE_IN_USE;
15096                            app.adjSource = a;
15097                            app.adjSourceOom = adj;
15098                            app.adjTarget = s.name;
15099                        }
15100                    }
15101                }
15102            }
15103        }
15104
15105        for (int provi = app.pubProviders.size()-1;
15106                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15107                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15108                        || procState > ActivityManager.PROCESS_STATE_TOP);
15109                provi--) {
15110            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15111            for (int i = cpr.connections.size()-1;
15112                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15113                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15114                            || procState > ActivityManager.PROCESS_STATE_TOP);
15115                    i--) {
15116                ContentProviderConnection conn = cpr.connections.get(i);
15117                ProcessRecord client = conn.client;
15118                if (client == app) {
15119                    // Being our own client is not interesting.
15120                    continue;
15121                }
15122                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15123                int clientProcState = client.curProcState;
15124                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15125                    // If the other app is cached for any reason, for purposes here
15126                    // we are going to consider it empty.
15127                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15128                }
15129                if (adj > clientAdj) {
15130                    if (app.hasShownUi && app != mHomeProcess
15131                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15132                        app.adjType = "cch-ui-provider";
15133                    } else {
15134                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15135                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15136                        app.adjType = "provider";
15137                    }
15138                    app.cached &= client.cached;
15139                    app.keeping |= client.keeping;
15140                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15141                            .REASON_PROVIDER_IN_USE;
15142                    app.adjSource = client;
15143                    app.adjSourceOom = clientAdj;
15144                    app.adjTarget = cpr.name;
15145                }
15146                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15147                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15148                        // Special handling of clients who are in the top state.
15149                        // We *may* want to consider this process to be in the
15150                        // top state as well, but only if there is not another
15151                        // reason for it to be running.  Being on the top is a
15152                        // special state, meaning you are specifically running
15153                        // for the current top app.  If the process is already
15154                        // running in the background for some other reason, it
15155                        // is more important to continue considering it to be
15156                        // in the background state.
15157                        mayBeTop = true;
15158                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15159                    } else {
15160                        // Special handling for above-top states (persistent
15161                        // processes).  These should not bring the current process
15162                        // into the top state, since they are not on top.  Instead
15163                        // give them the best state after that.
15164                        clientProcState =
15165                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15166                    }
15167                }
15168                if (procState > clientProcState) {
15169                    procState = clientProcState;
15170                }
15171                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15172                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15173                }
15174            }
15175            // If the provider has external (non-framework) process
15176            // dependencies, ensure that its adjustment is at least
15177            // FOREGROUND_APP_ADJ.
15178            if (cpr.hasExternalProcessHandles()) {
15179                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15180                    adj = ProcessList.FOREGROUND_APP_ADJ;
15181                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15182                    app.cached = false;
15183                    app.keeping = true;
15184                    app.adjType = "provider";
15185                    app.adjTarget = cpr.name;
15186                }
15187                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15188                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15189                }
15190            }
15191        }
15192
15193        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15194            // A client of one of our services or providers is in the top state.  We
15195            // *may* want to be in the top state, but not if we are already running in
15196            // the background for some other reason.  For the decision here, we are going
15197            // to pick out a few specific states that we want to remain in when a client
15198            // is top (states that tend to be longer-term) and otherwise allow it to go
15199            // to the top state.
15200            switch (procState) {
15201                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15202                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15203                case ActivityManager.PROCESS_STATE_SERVICE:
15204                    // These all are longer-term states, so pull them up to the top
15205                    // of the background states, but not all the way to the top state.
15206                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15207                    break;
15208                default:
15209                    // Otherwise, top is a better choice, so take it.
15210                    procState = ActivityManager.PROCESS_STATE_TOP;
15211                    break;
15212            }
15213        }
15214
15215        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15216            if (app.hasClientActivities) {
15217                // This is a cached process, but with client activities.  Mark it so.
15218                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15219                app.adjType = "cch-client-act";
15220            } else if (app.treatLikeActivity) {
15221                // This is a cached process, but somebody wants us to treat it like it has
15222                // an activity, okay!
15223                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15224                app.adjType = "cch-as-act";
15225            }
15226        }
15227
15228        if (adj == ProcessList.SERVICE_ADJ) {
15229            if (doingAll) {
15230                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15231                mNewNumServiceProcs++;
15232                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15233                if (!app.serviceb) {
15234                    // This service isn't far enough down on the LRU list to
15235                    // normally be a B service, but if we are low on RAM and it
15236                    // is large we want to force it down since we would prefer to
15237                    // keep launcher over it.
15238                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15239                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15240                        app.serviceHighRam = true;
15241                        app.serviceb = true;
15242                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15243                    } else {
15244                        mNewNumAServiceProcs++;
15245                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15246                    }
15247                } else {
15248                    app.serviceHighRam = false;
15249                }
15250            }
15251            if (app.serviceb) {
15252                adj = ProcessList.SERVICE_B_ADJ;
15253            }
15254        }
15255
15256        app.curRawAdj = adj;
15257
15258        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15259        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15260        if (adj > app.maxAdj) {
15261            adj = app.maxAdj;
15262            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15263                schedGroup = Process.THREAD_GROUP_DEFAULT;
15264            }
15265        }
15266        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15267            app.keeping = true;
15268        }
15269
15270        // Do final modification to adj.  Everything we do between here and applying
15271        // the final setAdj must be done in this function, because we will also use
15272        // it when computing the final cached adj later.  Note that we don't need to
15273        // worry about this for max adj above, since max adj will always be used to
15274        // keep it out of the cached vaues.
15275        app.curAdj = app.modifyRawOomAdj(adj);
15276        app.curSchedGroup = schedGroup;
15277        app.curProcState = procState;
15278        app.foregroundActivities = foregroundActivities;
15279
15280        return app.curRawAdj;
15281    }
15282
15283    /**
15284     * Schedule PSS collection of a process.
15285     */
15286    void requestPssLocked(ProcessRecord proc, int procState) {
15287        if (mPendingPssProcesses.contains(proc)) {
15288            return;
15289        }
15290        if (mPendingPssProcesses.size() == 0) {
15291            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15292        }
15293        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15294        proc.pssProcState = procState;
15295        mPendingPssProcesses.add(proc);
15296    }
15297
15298    /**
15299     * Schedule PSS collection of all processes.
15300     */
15301    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15302        if (!always) {
15303            if (now < (mLastFullPssTime +
15304                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15305                return;
15306            }
15307        }
15308        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15309        mLastFullPssTime = now;
15310        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15311        mPendingPssProcesses.clear();
15312        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15313            ProcessRecord app = mLruProcesses.get(i);
15314            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15315                app.pssProcState = app.setProcState;
15316                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15317                        isSleeping(), now);
15318                mPendingPssProcesses.add(app);
15319            }
15320        }
15321        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15322    }
15323
15324    /**
15325     * Ask a given process to GC right now.
15326     */
15327    final void performAppGcLocked(ProcessRecord app) {
15328        try {
15329            app.lastRequestedGc = SystemClock.uptimeMillis();
15330            if (app.thread != null) {
15331                if (app.reportLowMemory) {
15332                    app.reportLowMemory = false;
15333                    app.thread.scheduleLowMemory();
15334                } else {
15335                    app.thread.processInBackground();
15336                }
15337            }
15338        } catch (Exception e) {
15339            // whatever.
15340        }
15341    }
15342
15343    /**
15344     * Returns true if things are idle enough to perform GCs.
15345     */
15346    private final boolean canGcNowLocked() {
15347        boolean processingBroadcasts = false;
15348        for (BroadcastQueue q : mBroadcastQueues) {
15349            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15350                processingBroadcasts = true;
15351            }
15352        }
15353        return !processingBroadcasts
15354                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15355    }
15356
15357    /**
15358     * Perform GCs on all processes that are waiting for it, but only
15359     * if things are idle.
15360     */
15361    final void performAppGcsLocked() {
15362        final int N = mProcessesToGc.size();
15363        if (N <= 0) {
15364            return;
15365        }
15366        if (canGcNowLocked()) {
15367            while (mProcessesToGc.size() > 0) {
15368                ProcessRecord proc = mProcessesToGc.remove(0);
15369                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15370                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15371                            <= SystemClock.uptimeMillis()) {
15372                        // To avoid spamming the system, we will GC processes one
15373                        // at a time, waiting a few seconds between each.
15374                        performAppGcLocked(proc);
15375                        scheduleAppGcsLocked();
15376                        return;
15377                    } else {
15378                        // It hasn't been long enough since we last GCed this
15379                        // process...  put it in the list to wait for its time.
15380                        addProcessToGcListLocked(proc);
15381                        break;
15382                    }
15383                }
15384            }
15385
15386            scheduleAppGcsLocked();
15387        }
15388    }
15389
15390    /**
15391     * If all looks good, perform GCs on all processes waiting for them.
15392     */
15393    final void performAppGcsIfAppropriateLocked() {
15394        if (canGcNowLocked()) {
15395            performAppGcsLocked();
15396            return;
15397        }
15398        // Still not idle, wait some more.
15399        scheduleAppGcsLocked();
15400    }
15401
15402    /**
15403     * Schedule the execution of all pending app GCs.
15404     */
15405    final void scheduleAppGcsLocked() {
15406        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15407
15408        if (mProcessesToGc.size() > 0) {
15409            // Schedule a GC for the time to the next process.
15410            ProcessRecord proc = mProcessesToGc.get(0);
15411            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15412
15413            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15414            long now = SystemClock.uptimeMillis();
15415            if (when < (now+GC_TIMEOUT)) {
15416                when = now + GC_TIMEOUT;
15417            }
15418            mHandler.sendMessageAtTime(msg, when);
15419        }
15420    }
15421
15422    /**
15423     * Add a process to the array of processes waiting to be GCed.  Keeps the
15424     * list in sorted order by the last GC time.  The process can't already be
15425     * on the list.
15426     */
15427    final void addProcessToGcListLocked(ProcessRecord proc) {
15428        boolean added = false;
15429        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15430            if (mProcessesToGc.get(i).lastRequestedGc <
15431                    proc.lastRequestedGc) {
15432                added = true;
15433                mProcessesToGc.add(i+1, proc);
15434                break;
15435            }
15436        }
15437        if (!added) {
15438            mProcessesToGc.add(0, proc);
15439        }
15440    }
15441
15442    /**
15443     * Set up to ask a process to GC itself.  This will either do it
15444     * immediately, or put it on the list of processes to gc the next
15445     * time things are idle.
15446     */
15447    final void scheduleAppGcLocked(ProcessRecord app) {
15448        long now = SystemClock.uptimeMillis();
15449        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15450            return;
15451        }
15452        if (!mProcessesToGc.contains(app)) {
15453            addProcessToGcListLocked(app);
15454            scheduleAppGcsLocked();
15455        }
15456    }
15457
15458    final void checkExcessivePowerUsageLocked(boolean doKills) {
15459        updateCpuStatsNow();
15460
15461        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15462        boolean doWakeKills = doKills;
15463        boolean doCpuKills = doKills;
15464        if (mLastPowerCheckRealtime == 0) {
15465            doWakeKills = false;
15466        }
15467        if (mLastPowerCheckUptime == 0) {
15468            doCpuKills = false;
15469        }
15470        if (stats.isScreenOn()) {
15471            doWakeKills = false;
15472        }
15473        final long curRealtime = SystemClock.elapsedRealtime();
15474        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15475        final long curUptime = SystemClock.uptimeMillis();
15476        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15477        mLastPowerCheckRealtime = curRealtime;
15478        mLastPowerCheckUptime = curUptime;
15479        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15480            doWakeKills = false;
15481        }
15482        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15483            doCpuKills = false;
15484        }
15485        int i = mLruProcesses.size();
15486        while (i > 0) {
15487            i--;
15488            ProcessRecord app = mLruProcesses.get(i);
15489            if (!app.keeping) {
15490                long wtime;
15491                synchronized (stats) {
15492                    wtime = stats.getProcessWakeTime(app.info.uid,
15493                            app.pid, curRealtime);
15494                }
15495                long wtimeUsed = wtime - app.lastWakeTime;
15496                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15497                if (DEBUG_POWER) {
15498                    StringBuilder sb = new StringBuilder(128);
15499                    sb.append("Wake for ");
15500                    app.toShortString(sb);
15501                    sb.append(": over ");
15502                    TimeUtils.formatDuration(realtimeSince, sb);
15503                    sb.append(" used ");
15504                    TimeUtils.formatDuration(wtimeUsed, sb);
15505                    sb.append(" (");
15506                    sb.append((wtimeUsed*100)/realtimeSince);
15507                    sb.append("%)");
15508                    Slog.i(TAG, sb.toString());
15509                    sb.setLength(0);
15510                    sb.append("CPU for ");
15511                    app.toShortString(sb);
15512                    sb.append(": over ");
15513                    TimeUtils.formatDuration(uptimeSince, sb);
15514                    sb.append(" used ");
15515                    TimeUtils.formatDuration(cputimeUsed, sb);
15516                    sb.append(" (");
15517                    sb.append((cputimeUsed*100)/uptimeSince);
15518                    sb.append("%)");
15519                    Slog.i(TAG, sb.toString());
15520                }
15521                // If a process has held a wake lock for more
15522                // than 50% of the time during this period,
15523                // that sounds bad.  Kill!
15524                if (doWakeKills && realtimeSince > 0
15525                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15526                    synchronized (stats) {
15527                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15528                                realtimeSince, wtimeUsed);
15529                    }
15530                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15531                            + " during " + realtimeSince);
15532                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15533                } else if (doCpuKills && uptimeSince > 0
15534                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15535                    synchronized (stats) {
15536                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15537                                uptimeSince, cputimeUsed);
15538                    }
15539                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15540                            + " during " + uptimeSince);
15541                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15542                } else {
15543                    app.lastWakeTime = wtime;
15544                    app.lastCpuTime = app.curCpuTime;
15545                }
15546            }
15547        }
15548    }
15549
15550    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15551            ProcessRecord TOP_APP, boolean doingAll, long now) {
15552        boolean success = true;
15553
15554        if (app.curRawAdj != app.setRawAdj) {
15555            if (wasKeeping && !app.keeping) {
15556                // This app is no longer something we want to keep.  Note
15557                // its current wake lock time to later know to kill it if
15558                // it is not behaving well.
15559                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15560                synchronized (stats) {
15561                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15562                            app.pid, SystemClock.elapsedRealtime());
15563                }
15564                app.lastCpuTime = app.curCpuTime;
15565            }
15566
15567            app.setRawAdj = app.curRawAdj;
15568        }
15569
15570        int changes = 0;
15571
15572        if (app.curAdj != app.setAdj) {
15573            ProcessList.setOomAdj(app.pid, app.curAdj);
15574            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15575                TAG, "Set " + app.pid + " " + app.processName +
15576                " adj " + app.curAdj + ": " + app.adjType);
15577            app.setAdj = app.curAdj;
15578        }
15579
15580        if (app.setSchedGroup != app.curSchedGroup) {
15581            app.setSchedGroup = app.curSchedGroup;
15582            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15583                    "Setting process group of " + app.processName
15584                    + " to " + app.curSchedGroup);
15585            if (app.waitingToKill != null &&
15586                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15587                killUnneededProcessLocked(app, app.waitingToKill);
15588                success = false;
15589            } else {
15590                if (true) {
15591                    long oldId = Binder.clearCallingIdentity();
15592                    try {
15593                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15594                    } catch (Exception e) {
15595                        Slog.w(TAG, "Failed setting process group of " + app.pid
15596                                + " to " + app.curSchedGroup);
15597                        e.printStackTrace();
15598                    } finally {
15599                        Binder.restoreCallingIdentity(oldId);
15600                    }
15601                } else {
15602                    if (app.thread != null) {
15603                        try {
15604                            app.thread.setSchedulingGroup(app.curSchedGroup);
15605                        } catch (RemoteException e) {
15606                        }
15607                    }
15608                }
15609                Process.setSwappiness(app.pid,
15610                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15611            }
15612        }
15613        if (app.repForegroundActivities != app.foregroundActivities) {
15614            app.repForegroundActivities = app.foregroundActivities;
15615            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15616        }
15617        if (app.repProcState != app.curProcState) {
15618            app.repProcState = app.curProcState;
15619            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15620            if (app.thread != null) {
15621                try {
15622                    if (false) {
15623                        //RuntimeException h = new RuntimeException("here");
15624                        Slog.i(TAG, "Sending new process state " + app.repProcState
15625                                + " to " + app /*, h*/);
15626                    }
15627                    app.thread.setProcessState(app.repProcState);
15628                } catch (RemoteException e) {
15629                }
15630            }
15631        }
15632        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15633                app.setProcState)) {
15634            app.lastStateTime = now;
15635            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15636                    isSleeping(), now);
15637            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15638                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15639                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15640                    + (app.nextPssTime-now) + ": " + app);
15641        } else {
15642            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15643                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15644                requestPssLocked(app, app.setProcState);
15645                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15646                        isSleeping(), now);
15647            } else if (false && DEBUG_PSS) {
15648                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15649            }
15650        }
15651        if (app.setProcState != app.curProcState) {
15652            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15653                    "Proc state change of " + app.processName
15654                    + " to " + app.curProcState);
15655            app.setProcState = app.curProcState;
15656            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15657                app.notCachedSinceIdle = false;
15658            }
15659            if (!doingAll) {
15660                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15661            } else {
15662                app.procStateChanged = true;
15663            }
15664        }
15665
15666        if (changes != 0) {
15667            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15668            int i = mPendingProcessChanges.size()-1;
15669            ProcessChangeItem item = null;
15670            while (i >= 0) {
15671                item = mPendingProcessChanges.get(i);
15672                if (item.pid == app.pid) {
15673                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15674                    break;
15675                }
15676                i--;
15677            }
15678            if (i < 0) {
15679                // No existing item in pending changes; need a new one.
15680                final int NA = mAvailProcessChanges.size();
15681                if (NA > 0) {
15682                    item = mAvailProcessChanges.remove(NA-1);
15683                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15684                } else {
15685                    item = new ProcessChangeItem();
15686                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15687                }
15688                item.changes = 0;
15689                item.pid = app.pid;
15690                item.uid = app.info.uid;
15691                if (mPendingProcessChanges.size() == 0) {
15692                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15693                            "*** Enqueueing dispatch processes changed!");
15694                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15695                }
15696                mPendingProcessChanges.add(item);
15697            }
15698            item.changes |= changes;
15699            item.processState = app.repProcState;
15700            item.foregroundActivities = app.repForegroundActivities;
15701            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15702                    + Integer.toHexString(System.identityHashCode(item))
15703                    + " " + app.toShortString() + ": changes=" + item.changes
15704                    + " procState=" + item.processState
15705                    + " foreground=" + item.foregroundActivities
15706                    + " type=" + app.adjType + " source=" + app.adjSource
15707                    + " target=" + app.adjTarget);
15708        }
15709
15710        return success;
15711    }
15712
15713    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15714        if (proc.thread != null && proc.baseProcessTracker != null) {
15715            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15716        }
15717    }
15718
15719    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15720            ProcessRecord TOP_APP, boolean doingAll, long now) {
15721        if (app.thread == null) {
15722            return false;
15723        }
15724
15725        final boolean wasKeeping = app.keeping;
15726
15727        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15728
15729        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15730    }
15731
15732    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15733            boolean oomAdj) {
15734        if (isForeground != proc.foregroundServices) {
15735            proc.foregroundServices = isForeground;
15736            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15737                    proc.info.uid);
15738            if (isForeground) {
15739                if (curProcs == null) {
15740                    curProcs = new ArrayList<ProcessRecord>();
15741                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15742                }
15743                if (!curProcs.contains(proc)) {
15744                    curProcs.add(proc);
15745                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15746                            proc.info.packageName, proc.info.uid);
15747                }
15748            } else {
15749                if (curProcs != null) {
15750                    if (curProcs.remove(proc)) {
15751                        mBatteryStatsService.noteEvent(
15752                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15753                                proc.info.packageName, proc.info.uid);
15754                        if (curProcs.size() <= 0) {
15755                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15756                        }
15757                    }
15758                }
15759            }
15760            if (oomAdj) {
15761                updateOomAdjLocked();
15762            }
15763        }
15764    }
15765
15766    private final ActivityRecord resumedAppLocked() {
15767        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15768        String pkg;
15769        int uid;
15770        if (act != null && !act.sleeping) {
15771            pkg = act.packageName;
15772            uid = act.info.applicationInfo.uid;
15773        } else {
15774            pkg = null;
15775            uid = -1;
15776        }
15777        // Has the UID or resumed package name changed?
15778        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15779                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15780            if (mCurResumedPackage != null) {
15781                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15782                        mCurResumedPackage, mCurResumedUid);
15783            }
15784            mCurResumedPackage = pkg;
15785            mCurResumedUid = uid;
15786            if (mCurResumedPackage != null) {
15787                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15788                        mCurResumedPackage, mCurResumedUid);
15789            }
15790        }
15791        return act;
15792    }
15793
15794    final boolean updateOomAdjLocked(ProcessRecord app) {
15795        final ActivityRecord TOP_ACT = resumedAppLocked();
15796        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15797        final boolean wasCached = app.cached;
15798
15799        mAdjSeq++;
15800
15801        // This is the desired cached adjusment we want to tell it to use.
15802        // If our app is currently cached, we know it, and that is it.  Otherwise,
15803        // we don't know it yet, and it needs to now be cached we will then
15804        // need to do a complete oom adj.
15805        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15806                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15807        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15808                SystemClock.uptimeMillis());
15809        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15810            // Changed to/from cached state, so apps after it in the LRU
15811            // list may also be changed.
15812            updateOomAdjLocked();
15813        }
15814        return success;
15815    }
15816
15817    final void updateOomAdjLocked() {
15818        final ActivityRecord TOP_ACT = resumedAppLocked();
15819        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15820        final long now = SystemClock.uptimeMillis();
15821        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15822        final int N = mLruProcesses.size();
15823
15824        if (false) {
15825            RuntimeException e = new RuntimeException();
15826            e.fillInStackTrace();
15827            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15828        }
15829
15830        mAdjSeq++;
15831        mNewNumServiceProcs = 0;
15832        mNewNumAServiceProcs = 0;
15833
15834        final int emptyProcessLimit;
15835        final int cachedProcessLimit;
15836        if (mProcessLimit <= 0) {
15837            emptyProcessLimit = cachedProcessLimit = 0;
15838        } else if (mProcessLimit == 1) {
15839            emptyProcessLimit = 1;
15840            cachedProcessLimit = 0;
15841        } else {
15842            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15843            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15844        }
15845
15846        // Let's determine how many processes we have running vs.
15847        // how many slots we have for background processes; we may want
15848        // to put multiple processes in a slot of there are enough of
15849        // them.
15850        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15851                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15852        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15853        if (numEmptyProcs > cachedProcessLimit) {
15854            // If there are more empty processes than our limit on cached
15855            // processes, then use the cached process limit for the factor.
15856            // This ensures that the really old empty processes get pushed
15857            // down to the bottom, so if we are running low on memory we will
15858            // have a better chance at keeping around more cached processes
15859            // instead of a gazillion empty processes.
15860            numEmptyProcs = cachedProcessLimit;
15861        }
15862        int emptyFactor = numEmptyProcs/numSlots;
15863        if (emptyFactor < 1) emptyFactor = 1;
15864        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15865        if (cachedFactor < 1) cachedFactor = 1;
15866        int stepCached = 0;
15867        int stepEmpty = 0;
15868        int numCached = 0;
15869        int numEmpty = 0;
15870        int numTrimming = 0;
15871
15872        mNumNonCachedProcs = 0;
15873        mNumCachedHiddenProcs = 0;
15874
15875        // First update the OOM adjustment for each of the
15876        // application processes based on their current state.
15877        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15878        int nextCachedAdj = curCachedAdj+1;
15879        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15880        int nextEmptyAdj = curEmptyAdj+2;
15881        for (int i=N-1; i>=0; i--) {
15882            ProcessRecord app = mLruProcesses.get(i);
15883            if (!app.killedByAm && app.thread != null) {
15884                app.procStateChanged = false;
15885                final boolean wasKeeping = app.keeping;
15886                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15887
15888                // If we haven't yet assigned the final cached adj
15889                // to the process, do that now.
15890                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15891                    switch (app.curProcState) {
15892                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15893                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15894                            // This process is a cached process holding activities...
15895                            // assign it the next cached value for that type, and then
15896                            // step that cached level.
15897                            app.curRawAdj = curCachedAdj;
15898                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15899                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15900                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15901                                    + ")");
15902                            if (curCachedAdj != nextCachedAdj) {
15903                                stepCached++;
15904                                if (stepCached >= cachedFactor) {
15905                                    stepCached = 0;
15906                                    curCachedAdj = nextCachedAdj;
15907                                    nextCachedAdj += 2;
15908                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15909                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15910                                    }
15911                                }
15912                            }
15913                            break;
15914                        default:
15915                            // For everything else, assign next empty cached process
15916                            // level and bump that up.  Note that this means that
15917                            // long-running services that have dropped down to the
15918                            // cached level will be treated as empty (since their process
15919                            // state is still as a service), which is what we want.
15920                            app.curRawAdj = curEmptyAdj;
15921                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15922                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15923                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15924                                    + ")");
15925                            if (curEmptyAdj != nextEmptyAdj) {
15926                                stepEmpty++;
15927                                if (stepEmpty >= emptyFactor) {
15928                                    stepEmpty = 0;
15929                                    curEmptyAdj = nextEmptyAdj;
15930                                    nextEmptyAdj += 2;
15931                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15932                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15933                                    }
15934                                }
15935                            }
15936                            break;
15937                    }
15938                }
15939
15940                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15941
15942                // Count the number of process types.
15943                switch (app.curProcState) {
15944                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15945                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15946                        mNumCachedHiddenProcs++;
15947                        numCached++;
15948                        if (numCached > cachedProcessLimit) {
15949                            killUnneededProcessLocked(app, "cached #" + numCached);
15950                        }
15951                        break;
15952                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15953                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15954                                && app.lastActivityTime < oldTime) {
15955                            killUnneededProcessLocked(app, "empty for "
15956                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15957                                    / 1000) + "s");
15958                        } else {
15959                            numEmpty++;
15960                            if (numEmpty > emptyProcessLimit) {
15961                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15962                            }
15963                        }
15964                        break;
15965                    default:
15966                        mNumNonCachedProcs++;
15967                        break;
15968                }
15969
15970                if (app.isolated && app.services.size() <= 0) {
15971                    // If this is an isolated process, and there are no
15972                    // services running in it, then the process is no longer
15973                    // needed.  We agressively kill these because we can by
15974                    // definition not re-use the same process again, and it is
15975                    // good to avoid having whatever code was running in them
15976                    // left sitting around after no longer needed.
15977                    killUnneededProcessLocked(app, "isolated not needed");
15978                }
15979
15980                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15981                        && !app.killedByAm) {
15982                    numTrimming++;
15983                }
15984            }
15985        }
15986
15987        mNumServiceProcs = mNewNumServiceProcs;
15988
15989        // Now determine the memory trimming level of background processes.
15990        // Unfortunately we need to start at the back of the list to do this
15991        // properly.  We only do this if the number of background apps we
15992        // are managing to keep around is less than half the maximum we desire;
15993        // if we are keeping a good number around, we'll let them use whatever
15994        // memory they want.
15995        final int numCachedAndEmpty = numCached + numEmpty;
15996        int memFactor;
15997        if (numCached <= ProcessList.TRIM_CACHED_APPS
15998                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15999            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16000                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16001            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16002                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16003            } else {
16004                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16005            }
16006        } else {
16007            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16008        }
16009        // We always allow the memory level to go up (better).  We only allow it to go
16010        // down if we are in a state where that is allowed, *and* the total number of processes
16011        // has gone down since last time.
16012        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16013                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16014                + " last=" + mLastNumProcesses);
16015        if (memFactor > mLastMemoryLevel) {
16016            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16017                memFactor = mLastMemoryLevel;
16018                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16019            }
16020        }
16021        mLastMemoryLevel = memFactor;
16022        mLastNumProcesses = mLruProcesses.size();
16023        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16024        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16025        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16026            if (mLowRamStartTime == 0) {
16027                mLowRamStartTime = now;
16028            }
16029            int step = 0;
16030            int fgTrimLevel;
16031            switch (memFactor) {
16032                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16033                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16034                    break;
16035                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16036                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16037                    break;
16038                default:
16039                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16040                    break;
16041            }
16042            int factor = numTrimming/3;
16043            int minFactor = 2;
16044            if (mHomeProcess != null) minFactor++;
16045            if (mPreviousProcess != null) minFactor++;
16046            if (factor < minFactor) factor = minFactor;
16047            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16048            for (int i=N-1; i>=0; i--) {
16049                ProcessRecord app = mLruProcesses.get(i);
16050                if (allChanged || app.procStateChanged) {
16051                    setProcessTrackerState(app, trackerMemFactor, now);
16052                    app.procStateChanged = false;
16053                }
16054                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16055                        && !app.killedByAm) {
16056                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16057                        try {
16058                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16059                                    "Trimming memory of " + app.processName
16060                                    + " to " + curLevel);
16061                            app.thread.scheduleTrimMemory(curLevel);
16062                        } catch (RemoteException e) {
16063                        }
16064                        if (false) {
16065                            // For now we won't do this; our memory trimming seems
16066                            // to be good enough at this point that destroying
16067                            // activities causes more harm than good.
16068                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16069                                    && app != mHomeProcess && app != mPreviousProcess) {
16070                                // Need to do this on its own message because the stack may not
16071                                // be in a consistent state at this point.
16072                                // For these apps we will also finish their activities
16073                                // to help them free memory.
16074                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16075                            }
16076                        }
16077                    }
16078                    app.trimMemoryLevel = curLevel;
16079                    step++;
16080                    if (step >= factor) {
16081                        step = 0;
16082                        switch (curLevel) {
16083                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16084                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16085                                break;
16086                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16087                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16088                                break;
16089                        }
16090                    }
16091                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16092                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16093                            && app.thread != null) {
16094                        try {
16095                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16096                                    "Trimming memory of heavy-weight " + app.processName
16097                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16098                            app.thread.scheduleTrimMemory(
16099                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16100                        } catch (RemoteException e) {
16101                        }
16102                    }
16103                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16104                } else {
16105                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16106                            || app.systemNoUi) && app.pendingUiClean) {
16107                        // If this application is now in the background and it
16108                        // had done UI, then give it the special trim level to
16109                        // have it free UI resources.
16110                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16111                        if (app.trimMemoryLevel < level && app.thread != null) {
16112                            try {
16113                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16114                                        "Trimming memory of bg-ui " + app.processName
16115                                        + " to " + level);
16116                                app.thread.scheduleTrimMemory(level);
16117                            } catch (RemoteException e) {
16118                            }
16119                        }
16120                        app.pendingUiClean = false;
16121                    }
16122                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16123                        try {
16124                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16125                                    "Trimming memory of fg " + app.processName
16126                                    + " to " + fgTrimLevel);
16127                            app.thread.scheduleTrimMemory(fgTrimLevel);
16128                        } catch (RemoteException e) {
16129                        }
16130                    }
16131                    app.trimMemoryLevel = fgTrimLevel;
16132                }
16133            }
16134        } else {
16135            if (mLowRamStartTime != 0) {
16136                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16137                mLowRamStartTime = 0;
16138            }
16139            for (int i=N-1; i>=0; i--) {
16140                ProcessRecord app = mLruProcesses.get(i);
16141                if (allChanged || app.procStateChanged) {
16142                    setProcessTrackerState(app, trackerMemFactor, now);
16143                    app.procStateChanged = false;
16144                }
16145                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16146                        || app.systemNoUi) && app.pendingUiClean) {
16147                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16148                            && app.thread != null) {
16149                        try {
16150                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16151                                    "Trimming memory of ui hidden " + app.processName
16152                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16153                            app.thread.scheduleTrimMemory(
16154                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16155                        } catch (RemoteException e) {
16156                        }
16157                    }
16158                    app.pendingUiClean = false;
16159                }
16160                app.trimMemoryLevel = 0;
16161            }
16162        }
16163
16164        if (mAlwaysFinishActivities) {
16165            // Need to do this on its own message because the stack may not
16166            // be in a consistent state at this point.
16167            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16168        }
16169
16170        if (allChanged) {
16171            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16172        }
16173
16174        if (mProcessStats.shouldWriteNowLocked(now)) {
16175            mHandler.post(new Runnable() {
16176                @Override public void run() {
16177                    synchronized (ActivityManagerService.this) {
16178                        mProcessStats.writeStateAsyncLocked();
16179                    }
16180                }
16181            });
16182        }
16183
16184        if (DEBUG_OOM_ADJ) {
16185            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16186        }
16187    }
16188
16189    final void trimApplications() {
16190        synchronized (this) {
16191            int i;
16192
16193            // First remove any unused application processes whose package
16194            // has been removed.
16195            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16196                final ProcessRecord app = mRemovedProcesses.get(i);
16197                if (app.activities.size() == 0
16198                        && app.curReceiver == null && app.services.size() == 0) {
16199                    Slog.i(
16200                        TAG, "Exiting empty application process "
16201                        + app.processName + " ("
16202                        + (app.thread != null ? app.thread.asBinder() : null)
16203                        + ")\n");
16204                    if (app.pid > 0 && app.pid != MY_PID) {
16205                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16206                                app.processName, app.setAdj, "empty");
16207                        app.killedByAm = true;
16208                        Process.killProcessQuiet(app.pid);
16209                    } else {
16210                        try {
16211                            app.thread.scheduleExit();
16212                        } catch (Exception e) {
16213                            // Ignore exceptions.
16214                        }
16215                    }
16216                    cleanUpApplicationRecordLocked(app, false, true, -1);
16217                    mRemovedProcesses.remove(i);
16218
16219                    if (app.persistent) {
16220                        if (app.persistent) {
16221                            addAppLocked(app.info, false);
16222                        }
16223                    }
16224                }
16225            }
16226
16227            // Now update the oom adj for all processes.
16228            updateOomAdjLocked();
16229        }
16230    }
16231
16232    /** This method sends the specified signal to each of the persistent apps */
16233    public void signalPersistentProcesses(int sig) throws RemoteException {
16234        if (sig != Process.SIGNAL_USR1) {
16235            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16236        }
16237
16238        synchronized (this) {
16239            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16240                    != PackageManager.PERMISSION_GRANTED) {
16241                throw new SecurityException("Requires permission "
16242                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16243            }
16244
16245            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16246                ProcessRecord r = mLruProcesses.get(i);
16247                if (r.thread != null && r.persistent) {
16248                    Process.sendSignal(r.pid, sig);
16249                }
16250            }
16251        }
16252    }
16253
16254    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16255        if (proc == null || proc == mProfileProc) {
16256            proc = mProfileProc;
16257            path = mProfileFile;
16258            profileType = mProfileType;
16259            clearProfilerLocked();
16260        }
16261        if (proc == null) {
16262            return;
16263        }
16264        try {
16265            proc.thread.profilerControl(false, path, null, profileType);
16266        } catch (RemoteException e) {
16267            throw new IllegalStateException("Process disappeared");
16268        }
16269    }
16270
16271    private void clearProfilerLocked() {
16272        if (mProfileFd != null) {
16273            try {
16274                mProfileFd.close();
16275            } catch (IOException e) {
16276            }
16277        }
16278        mProfileApp = null;
16279        mProfileProc = null;
16280        mProfileFile = null;
16281        mProfileType = 0;
16282        mAutoStopProfiler = false;
16283    }
16284
16285    public boolean profileControl(String process, int userId, boolean start,
16286            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16287
16288        try {
16289            synchronized (this) {
16290                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16291                // its own permission.
16292                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16293                        != PackageManager.PERMISSION_GRANTED) {
16294                    throw new SecurityException("Requires permission "
16295                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16296                }
16297
16298                if (start && fd == null) {
16299                    throw new IllegalArgumentException("null fd");
16300                }
16301
16302                ProcessRecord proc = null;
16303                if (process != null) {
16304                    proc = findProcessLocked(process, userId, "profileControl");
16305                }
16306
16307                if (start && (proc == null || proc.thread == null)) {
16308                    throw new IllegalArgumentException("Unknown process: " + process);
16309                }
16310
16311                if (start) {
16312                    stopProfilerLocked(null, null, 0);
16313                    setProfileApp(proc.info, proc.processName, path, fd, false);
16314                    mProfileProc = proc;
16315                    mProfileType = profileType;
16316                    try {
16317                        fd = fd.dup();
16318                    } catch (IOException e) {
16319                        fd = null;
16320                    }
16321                    proc.thread.profilerControl(start, path, fd, profileType);
16322                    fd = null;
16323                    mProfileFd = null;
16324                } else {
16325                    stopProfilerLocked(proc, path, profileType);
16326                    if (fd != null) {
16327                        try {
16328                            fd.close();
16329                        } catch (IOException e) {
16330                        }
16331                    }
16332                }
16333
16334                return true;
16335            }
16336        } catch (RemoteException e) {
16337            throw new IllegalStateException("Process disappeared");
16338        } finally {
16339            if (fd != null) {
16340                try {
16341                    fd.close();
16342                } catch (IOException e) {
16343                }
16344            }
16345        }
16346    }
16347
16348    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16349        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16350                userId, true, true, callName, null);
16351        ProcessRecord proc = null;
16352        try {
16353            int pid = Integer.parseInt(process);
16354            synchronized (mPidsSelfLocked) {
16355                proc = mPidsSelfLocked.get(pid);
16356            }
16357        } catch (NumberFormatException e) {
16358        }
16359
16360        if (proc == null) {
16361            ArrayMap<String, SparseArray<ProcessRecord>> all
16362                    = mProcessNames.getMap();
16363            SparseArray<ProcessRecord> procs = all.get(process);
16364            if (procs != null && procs.size() > 0) {
16365                proc = procs.valueAt(0);
16366                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16367                    for (int i=1; i<procs.size(); i++) {
16368                        ProcessRecord thisProc = procs.valueAt(i);
16369                        if (thisProc.userId == userId) {
16370                            proc = thisProc;
16371                            break;
16372                        }
16373                    }
16374                }
16375            }
16376        }
16377
16378        return proc;
16379    }
16380
16381    public boolean dumpHeap(String process, int userId, boolean managed,
16382            String path, ParcelFileDescriptor fd) throws RemoteException {
16383
16384        try {
16385            synchronized (this) {
16386                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16387                // its own permission (same as profileControl).
16388                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16389                        != PackageManager.PERMISSION_GRANTED) {
16390                    throw new SecurityException("Requires permission "
16391                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16392                }
16393
16394                if (fd == null) {
16395                    throw new IllegalArgumentException("null fd");
16396                }
16397
16398                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16399                if (proc == null || proc.thread == null) {
16400                    throw new IllegalArgumentException("Unknown process: " + process);
16401                }
16402
16403                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16404                if (!isDebuggable) {
16405                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16406                        throw new SecurityException("Process not debuggable: " + proc);
16407                    }
16408                }
16409
16410                proc.thread.dumpHeap(managed, path, fd);
16411                fd = null;
16412                return true;
16413            }
16414        } catch (RemoteException e) {
16415            throw new IllegalStateException("Process disappeared");
16416        } finally {
16417            if (fd != null) {
16418                try {
16419                    fd.close();
16420                } catch (IOException e) {
16421                }
16422            }
16423        }
16424    }
16425
16426    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16427    public void monitor() {
16428        synchronized (this) { }
16429    }
16430
16431    void onCoreSettingsChange(Bundle settings) {
16432        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16433            ProcessRecord processRecord = mLruProcesses.get(i);
16434            try {
16435                if (processRecord.thread != null) {
16436                    processRecord.thread.setCoreSettings(settings);
16437                }
16438            } catch (RemoteException re) {
16439                /* ignore */
16440            }
16441        }
16442    }
16443
16444    // Multi-user methods
16445
16446    /**
16447     * Start user, if its not already running, but don't bring it to foreground.
16448     */
16449    @Override
16450    public boolean startUserInBackground(final int userId) {
16451        return startUser(userId, /* foreground */ false);
16452    }
16453
16454    /**
16455     * Refreshes the list of users related to the current user when either a
16456     * user switch happens or when a new related user is started in the
16457     * background.
16458     */
16459    private void updateCurrentProfileIdsLocked() {
16460        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16461                mCurrentUserId, false /* enabledOnly */);
16462        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16463        for (int i = 0; i < currentProfileIds.length; i++) {
16464            currentProfileIds[i] = profiles.get(i).id;
16465        }
16466        mCurrentProfileIds = currentProfileIds;
16467    }
16468
16469    private Set getProfileIdsLocked(int userId) {
16470        Set userIds = new HashSet<Integer>();
16471        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16472                userId, false /* enabledOnly */);
16473        for (UserInfo user : profiles) {
16474            userIds.add(Integer.valueOf(user.id));
16475        }
16476        return userIds;
16477    }
16478
16479    @Override
16480    public boolean switchUser(final int userId) {
16481        return startUser(userId, /* foregound */ true);
16482    }
16483
16484    private boolean startUser(final int userId, boolean foreground) {
16485        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16486                != PackageManager.PERMISSION_GRANTED) {
16487            String msg = "Permission Denial: switchUser() from pid="
16488                    + Binder.getCallingPid()
16489                    + ", uid=" + Binder.getCallingUid()
16490                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16491            Slog.w(TAG, msg);
16492            throw new SecurityException(msg);
16493        }
16494
16495        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16496
16497        final long ident = Binder.clearCallingIdentity();
16498        try {
16499            synchronized (this) {
16500                final int oldUserId = mCurrentUserId;
16501                if (oldUserId == userId) {
16502                    return true;
16503                }
16504
16505                mStackSupervisor.setLockTaskModeLocked(null);
16506
16507                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16508                if (userInfo == null) {
16509                    Slog.w(TAG, "No user info for user #" + userId);
16510                    return false;
16511                }
16512
16513                if (foreground) {
16514                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16515                            R.anim.screen_user_enter);
16516                }
16517
16518                boolean needStart = false;
16519
16520                // If the user we are switching to is not currently started, then
16521                // we need to start it now.
16522                if (mStartedUsers.get(userId) == null) {
16523                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16524                    updateStartedUserArrayLocked();
16525                    needStart = true;
16526                }
16527
16528                final Integer userIdInt = Integer.valueOf(userId);
16529                mUserLru.remove(userIdInt);
16530                mUserLru.add(userIdInt);
16531
16532                if (foreground) {
16533                    mCurrentUserId = userId;
16534                    updateCurrentProfileIdsLocked();
16535                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16536                    // Once the internal notion of the active user has switched, we lock the device
16537                    // with the option to show the user switcher on the keyguard.
16538                    mWindowManager.lockNow(null);
16539                } else {
16540                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16541                    updateCurrentProfileIdsLocked();
16542                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16543                    mUserLru.remove(currentUserIdInt);
16544                    mUserLru.add(currentUserIdInt);
16545                }
16546
16547                final UserStartedState uss = mStartedUsers.get(userId);
16548
16549                // Make sure user is in the started state.  If it is currently
16550                // stopping, we need to knock that off.
16551                if (uss.mState == UserStartedState.STATE_STOPPING) {
16552                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16553                    // so we can just fairly silently bring the user back from
16554                    // the almost-dead.
16555                    uss.mState = UserStartedState.STATE_RUNNING;
16556                    updateStartedUserArrayLocked();
16557                    needStart = true;
16558                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16559                    // This means ACTION_SHUTDOWN has been sent, so we will
16560                    // need to treat this as a new boot of the user.
16561                    uss.mState = UserStartedState.STATE_BOOTING;
16562                    updateStartedUserArrayLocked();
16563                    needStart = true;
16564                }
16565
16566                if (uss.mState == UserStartedState.STATE_BOOTING) {
16567                    // Booting up a new user, need to tell system services about it.
16568                    // Note that this is on the same handler as scheduling of broadcasts,
16569                    // which is important because it needs to go first.
16570                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16571                }
16572
16573                if (foreground) {
16574                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16575                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16576                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16577                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16578                            oldUserId, userId, uss));
16579                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16580                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16581                }
16582
16583                if (needStart) {
16584                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16585                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16586                            | Intent.FLAG_RECEIVER_FOREGROUND);
16587                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16588                    broadcastIntentLocked(null, null, intent,
16589                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16590                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16591                }
16592
16593                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16594                    if (userId != UserHandle.USER_OWNER) {
16595                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16596                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16597                        broadcastIntentLocked(null, null, intent, null,
16598                                new IIntentReceiver.Stub() {
16599                                    public void performReceive(Intent intent, int resultCode,
16600                                            String data, Bundle extras, boolean ordered,
16601                                            boolean sticky, int sendingUser) {
16602                                        userInitialized(uss, userId);
16603                                    }
16604                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16605                                true, false, MY_PID, Process.SYSTEM_UID,
16606                                userId);
16607                        uss.initializing = true;
16608                    } else {
16609                        getUserManagerLocked().makeInitialized(userInfo.id);
16610                    }
16611                }
16612
16613                if (foreground) {
16614                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16615                    if (homeInFront) {
16616                        startHomeActivityLocked(userId);
16617                    } else {
16618                        mStackSupervisor.resumeTopActivitiesLocked();
16619                    }
16620                    EventLogTags.writeAmSwitchUser(userId);
16621                    getUserManagerLocked().userForeground(userId);
16622                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16623                } else {
16624                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16625                }
16626
16627                if (needStart) {
16628                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16629                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16630                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16631                    broadcastIntentLocked(null, null, intent,
16632                            null, new IIntentReceiver.Stub() {
16633                                @Override
16634                                public void performReceive(Intent intent, int resultCode, String data,
16635                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16636                                        throws RemoteException {
16637                                }
16638                            }, 0, null, null,
16639                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16640                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16641                }
16642            }
16643        } finally {
16644            Binder.restoreCallingIdentity(ident);
16645        }
16646
16647        return true;
16648    }
16649
16650    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16651        long ident = Binder.clearCallingIdentity();
16652        try {
16653            Intent intent;
16654            if (oldUserId >= 0) {
16655                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16656                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16657                        | Intent.FLAG_RECEIVER_FOREGROUND);
16658                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16659                broadcastIntentLocked(null, null, intent,
16660                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16661                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16662            }
16663            if (newUserId >= 0) {
16664                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16665                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16666                        | Intent.FLAG_RECEIVER_FOREGROUND);
16667                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16668                broadcastIntentLocked(null, null, intent,
16669                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16670                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16671                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16672                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16673                        | Intent.FLAG_RECEIVER_FOREGROUND);
16674                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16675                broadcastIntentLocked(null, null, intent,
16676                        null, null, 0, null, null,
16677                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16678                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16679            }
16680        } finally {
16681            Binder.restoreCallingIdentity(ident);
16682        }
16683    }
16684
16685    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16686            final int newUserId) {
16687        final int N = mUserSwitchObservers.beginBroadcast();
16688        if (N > 0) {
16689            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16690                int mCount = 0;
16691                @Override
16692                public void sendResult(Bundle data) throws RemoteException {
16693                    synchronized (ActivityManagerService.this) {
16694                        if (mCurUserSwitchCallback == this) {
16695                            mCount++;
16696                            if (mCount == N) {
16697                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16698                            }
16699                        }
16700                    }
16701                }
16702            };
16703            synchronized (this) {
16704                uss.switching = true;
16705                mCurUserSwitchCallback = callback;
16706            }
16707            for (int i=0; i<N; i++) {
16708                try {
16709                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16710                            newUserId, callback);
16711                } catch (RemoteException e) {
16712                }
16713            }
16714        } else {
16715            synchronized (this) {
16716                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16717            }
16718        }
16719        mUserSwitchObservers.finishBroadcast();
16720    }
16721
16722    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16723        synchronized (this) {
16724            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16725            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16726        }
16727    }
16728
16729    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16730        mCurUserSwitchCallback = null;
16731        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16732        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16733                oldUserId, newUserId, uss));
16734    }
16735
16736    void userInitialized(UserStartedState uss, int newUserId) {
16737        completeSwitchAndInitalize(uss, newUserId, true, false);
16738    }
16739
16740    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16741        completeSwitchAndInitalize(uss, newUserId, false, true);
16742    }
16743
16744    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16745            boolean clearInitializing, boolean clearSwitching) {
16746        boolean unfrozen = false;
16747        synchronized (this) {
16748            if (clearInitializing) {
16749                uss.initializing = false;
16750                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16751            }
16752            if (clearSwitching) {
16753                uss.switching = false;
16754            }
16755            if (!uss.switching && !uss.initializing) {
16756                mWindowManager.stopFreezingScreen();
16757                unfrozen = true;
16758            }
16759        }
16760        if (unfrozen) {
16761            final int N = mUserSwitchObservers.beginBroadcast();
16762            for (int i=0; i<N; i++) {
16763                try {
16764                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16765                } catch (RemoteException e) {
16766                }
16767            }
16768            mUserSwitchObservers.finishBroadcast();
16769        }
16770    }
16771
16772    void scheduleStartProfilesLocked() {
16773        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16774            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16775                    DateUtils.SECOND_IN_MILLIS);
16776        }
16777    }
16778
16779    void startProfilesLocked() {
16780        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16781        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16782                mCurrentUserId, false /* enabledOnly */);
16783        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16784        for (UserInfo user : profiles) {
16785            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16786                    && user.id != mCurrentUserId) {
16787                toStart.add(user);
16788            }
16789        }
16790        final int n = toStart.size();
16791        int i = 0;
16792        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16793            startUserInBackground(toStart.get(i).id);
16794        }
16795        if (i < n) {
16796            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16797        }
16798    }
16799
16800    void finishUserBoot(UserStartedState uss) {
16801        synchronized (this) {
16802            if (uss.mState == UserStartedState.STATE_BOOTING
16803                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16804                uss.mState = UserStartedState.STATE_RUNNING;
16805                final int userId = uss.mHandle.getIdentifier();
16806                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16807                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16808                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16809                broadcastIntentLocked(null, null, intent,
16810                        null, null, 0, null, null,
16811                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16812                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16813            }
16814        }
16815    }
16816
16817    void finishUserSwitch(UserStartedState uss) {
16818        synchronized (this) {
16819            finishUserBoot(uss);
16820
16821            startProfilesLocked();
16822
16823            int num = mUserLru.size();
16824            int i = 0;
16825            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16826                Integer oldUserId = mUserLru.get(i);
16827                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16828                if (oldUss == null) {
16829                    // Shouldn't happen, but be sane if it does.
16830                    mUserLru.remove(i);
16831                    num--;
16832                    continue;
16833                }
16834                if (oldUss.mState == UserStartedState.STATE_STOPPING
16835                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16836                    // This user is already stopping, doesn't count.
16837                    num--;
16838                    i++;
16839                    continue;
16840                }
16841                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16842                    // Owner and current can't be stopped, but count as running.
16843                    i++;
16844                    continue;
16845                }
16846                // This is a user to be stopped.
16847                stopUserLocked(oldUserId, null);
16848                num--;
16849                i++;
16850            }
16851        }
16852    }
16853
16854    @Override
16855    public int stopUser(final int userId, final IStopUserCallback callback) {
16856        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16857                != PackageManager.PERMISSION_GRANTED) {
16858            String msg = "Permission Denial: switchUser() from pid="
16859                    + Binder.getCallingPid()
16860                    + ", uid=" + Binder.getCallingUid()
16861                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16862            Slog.w(TAG, msg);
16863            throw new SecurityException(msg);
16864        }
16865        if (userId <= 0) {
16866            throw new IllegalArgumentException("Can't stop primary user " + userId);
16867        }
16868        synchronized (this) {
16869            return stopUserLocked(userId, callback);
16870        }
16871    }
16872
16873    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16874        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16875        if (mCurrentUserId == userId) {
16876            return ActivityManager.USER_OP_IS_CURRENT;
16877        }
16878
16879        final UserStartedState uss = mStartedUsers.get(userId);
16880        if (uss == null) {
16881            // User is not started, nothing to do...  but we do need to
16882            // callback if requested.
16883            if (callback != null) {
16884                mHandler.post(new Runnable() {
16885                    @Override
16886                    public void run() {
16887                        try {
16888                            callback.userStopped(userId);
16889                        } catch (RemoteException e) {
16890                        }
16891                    }
16892                });
16893            }
16894            return ActivityManager.USER_OP_SUCCESS;
16895        }
16896
16897        if (callback != null) {
16898            uss.mStopCallbacks.add(callback);
16899        }
16900
16901        if (uss.mState != UserStartedState.STATE_STOPPING
16902                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16903            uss.mState = UserStartedState.STATE_STOPPING;
16904            updateStartedUserArrayLocked();
16905
16906            long ident = Binder.clearCallingIdentity();
16907            try {
16908                // We are going to broadcast ACTION_USER_STOPPING and then
16909                // once that is done send a final ACTION_SHUTDOWN and then
16910                // stop the user.
16911                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16912                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16913                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16914                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16915                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16916                // This is the result receiver for the final shutdown broadcast.
16917                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16918                    @Override
16919                    public void performReceive(Intent intent, int resultCode, String data,
16920                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16921                        finishUserStop(uss);
16922                    }
16923                };
16924                // This is the result receiver for the initial stopping broadcast.
16925                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16926                    @Override
16927                    public void performReceive(Intent intent, int resultCode, String data,
16928                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16929                        // On to the next.
16930                        synchronized (ActivityManagerService.this) {
16931                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16932                                // Whoops, we are being started back up.  Abort, abort!
16933                                return;
16934                            }
16935                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16936                        }
16937                        mSystemServiceManager.stopUser(userId);
16938                        broadcastIntentLocked(null, null, shutdownIntent,
16939                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16940                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16941                    }
16942                };
16943                // Kick things off.
16944                broadcastIntentLocked(null, null, stoppingIntent,
16945                        null, stoppingReceiver, 0, null, null,
16946                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16947                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16948            } finally {
16949                Binder.restoreCallingIdentity(ident);
16950            }
16951        }
16952
16953        return ActivityManager.USER_OP_SUCCESS;
16954    }
16955
16956    void finishUserStop(UserStartedState uss) {
16957        final int userId = uss.mHandle.getIdentifier();
16958        boolean stopped;
16959        ArrayList<IStopUserCallback> callbacks;
16960        synchronized (this) {
16961            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16962            if (mStartedUsers.get(userId) != uss) {
16963                stopped = false;
16964            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16965                stopped = false;
16966            } else {
16967                stopped = true;
16968                // User can no longer run.
16969                mStartedUsers.remove(userId);
16970                mUserLru.remove(Integer.valueOf(userId));
16971                updateStartedUserArrayLocked();
16972
16973                // Clean up all state and processes associated with the user.
16974                // Kill all the processes for the user.
16975                forceStopUserLocked(userId, "finish user");
16976            }
16977        }
16978
16979        for (int i=0; i<callbacks.size(); i++) {
16980            try {
16981                if (stopped) callbacks.get(i).userStopped(userId);
16982                else callbacks.get(i).userStopAborted(userId);
16983            } catch (RemoteException e) {
16984            }
16985        }
16986
16987        if (stopped) {
16988            mSystemServiceManager.cleanupUser(userId);
16989            synchronized (this) {
16990                mStackSupervisor.removeUserLocked(userId);
16991            }
16992        }
16993    }
16994
16995    @Override
16996    public UserInfo getCurrentUser() {
16997        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16998                != PackageManager.PERMISSION_GRANTED) && (
16999                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17000                != PackageManager.PERMISSION_GRANTED)) {
17001            String msg = "Permission Denial: getCurrentUser() from pid="
17002                    + Binder.getCallingPid()
17003                    + ", uid=" + Binder.getCallingUid()
17004                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17005            Slog.w(TAG, msg);
17006            throw new SecurityException(msg);
17007        }
17008        synchronized (this) {
17009            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17010        }
17011    }
17012
17013    int getCurrentUserIdLocked() {
17014        return mCurrentUserId;
17015    }
17016
17017    @Override
17018    public boolean isUserRunning(int userId, boolean orStopped) {
17019        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17020                != PackageManager.PERMISSION_GRANTED) {
17021            String msg = "Permission Denial: isUserRunning() from pid="
17022                    + Binder.getCallingPid()
17023                    + ", uid=" + Binder.getCallingUid()
17024                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17025            Slog.w(TAG, msg);
17026            throw new SecurityException(msg);
17027        }
17028        synchronized (this) {
17029            return isUserRunningLocked(userId, orStopped);
17030        }
17031    }
17032
17033    boolean isUserRunningLocked(int userId, boolean orStopped) {
17034        UserStartedState state = mStartedUsers.get(userId);
17035        if (state == null) {
17036            return false;
17037        }
17038        if (orStopped) {
17039            return true;
17040        }
17041        return state.mState != UserStartedState.STATE_STOPPING
17042                && state.mState != UserStartedState.STATE_SHUTDOWN;
17043    }
17044
17045    @Override
17046    public int[] getRunningUserIds() {
17047        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17048                != PackageManager.PERMISSION_GRANTED) {
17049            String msg = "Permission Denial: isUserRunning() from pid="
17050                    + Binder.getCallingPid()
17051                    + ", uid=" + Binder.getCallingUid()
17052                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17053            Slog.w(TAG, msg);
17054            throw new SecurityException(msg);
17055        }
17056        synchronized (this) {
17057            return mStartedUserArray;
17058        }
17059    }
17060
17061    private void updateStartedUserArrayLocked() {
17062        int num = 0;
17063        for (int i=0; i<mStartedUsers.size();  i++) {
17064            UserStartedState uss = mStartedUsers.valueAt(i);
17065            // This list does not include stopping users.
17066            if (uss.mState != UserStartedState.STATE_STOPPING
17067                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17068                num++;
17069            }
17070        }
17071        mStartedUserArray = new int[num];
17072        num = 0;
17073        for (int i=0; i<mStartedUsers.size();  i++) {
17074            UserStartedState uss = mStartedUsers.valueAt(i);
17075            if (uss.mState != UserStartedState.STATE_STOPPING
17076                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17077                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17078                num++;
17079            }
17080        }
17081    }
17082
17083    @Override
17084    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17085        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17086                != PackageManager.PERMISSION_GRANTED) {
17087            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17088                    + Binder.getCallingPid()
17089                    + ", uid=" + Binder.getCallingUid()
17090                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17091            Slog.w(TAG, msg);
17092            throw new SecurityException(msg);
17093        }
17094
17095        mUserSwitchObservers.register(observer);
17096    }
17097
17098    @Override
17099    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17100        mUserSwitchObservers.unregister(observer);
17101    }
17102
17103    private boolean userExists(int userId) {
17104        if (userId == 0) {
17105            return true;
17106        }
17107        UserManagerService ums = getUserManagerLocked();
17108        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17109    }
17110
17111    int[] getUsersLocked() {
17112        UserManagerService ums = getUserManagerLocked();
17113        return ums != null ? ums.getUserIds() : new int[] { 0 };
17114    }
17115
17116    UserManagerService getUserManagerLocked() {
17117        if (mUserManager == null) {
17118            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17119            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17120        }
17121        return mUserManager;
17122    }
17123
17124    private int applyUserId(int uid, int userId) {
17125        return UserHandle.getUid(userId, uid);
17126    }
17127
17128    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17129        if (info == null) return null;
17130        ApplicationInfo newInfo = new ApplicationInfo(info);
17131        newInfo.uid = applyUserId(info.uid, userId);
17132        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17133                + info.packageName;
17134        return newInfo;
17135    }
17136
17137    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17138        if (aInfo == null
17139                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17140            return aInfo;
17141        }
17142
17143        ActivityInfo info = new ActivityInfo(aInfo);
17144        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17145        return info;
17146    }
17147
17148    private final class LocalService extends ActivityManagerInternal {
17149        @Override
17150        public void goingToSleep() {
17151            ActivityManagerService.this.goingToSleep();
17152        }
17153
17154        @Override
17155        public void wakingUp() {
17156            ActivityManagerService.this.wakingUp();
17157        }
17158    }
17159}
17160