ActivityManagerService.java revision 21d24a21ea4aaadd78e73de54168e8a8a8973e4d
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.Manifest;
32import android.app.AppOpsManager;
33import android.app.IActivityContainer;
34import android.app.IActivityContainerCallback;
35import android.app.IAppTask;
36import android.app.admin.DevicePolicyManager;
37import android.appwidget.AppWidgetManager;
38import android.graphics.Rect;
39import android.os.BatteryStats;
40import android.os.PersistableBundle;
41import android.service.voice.IVoiceInteractionSession;
42import android.util.ArrayMap;
43
44import com.android.internal.R;
45import com.android.internal.annotations.GuardedBy;
46import com.android.internal.app.IAppOpsService;
47import com.android.internal.app.IVoiceInteractor;
48import com.android.internal.app.ProcessMap;
49import com.android.internal.app.ProcessStats;
50import com.android.internal.content.PackageMonitor;
51import com.android.internal.os.BackgroundThread;
52import com.android.internal.os.BatteryStatsImpl;
53import com.android.internal.os.ProcessCpuTracker;
54import com.android.internal.os.TransferPipe;
55import com.android.internal.os.Zygote;
56import com.android.internal.util.FastPrintWriter;
57import com.android.internal.util.FastXmlSerializer;
58import com.android.internal.util.MemInfoReader;
59import com.android.internal.util.Preconditions;
60import com.android.server.AppOpsService;
61import com.android.server.AttributeCache;
62import com.android.server.IntentResolver;
63import com.android.server.LocalServices;
64import com.android.server.ServiceThread;
65import com.android.server.SystemService;
66import com.android.server.SystemServiceManager;
67import com.android.server.Watchdog;
68import com.android.server.am.ActivityStack.ActivityState;
69import com.android.server.firewall.IntentFirewall;
70import com.android.server.pm.UserManagerService;
71import com.android.server.wm.AppTransition;
72import com.android.server.wm.WindowManagerService;
73import com.google.android.collect.Lists;
74import com.google.android.collect.Maps;
75
76import libcore.io.IoUtils;
77
78import org.xmlpull.v1.XmlPullParser;
79import org.xmlpull.v1.XmlPullParserException;
80import org.xmlpull.v1.XmlSerializer;
81
82import android.app.Activity;
83import android.app.ActivityManager;
84import android.app.ActivityManager.RunningTaskInfo;
85import android.app.ActivityManager.StackInfo;
86import android.app.ActivityManagerInternal;
87import android.app.ActivityManagerNative;
88import android.app.ActivityOptions;
89import android.app.ActivityThread;
90import android.app.AlertDialog;
91import android.app.AppGlobals;
92import android.app.ApplicationErrorReport;
93import android.app.Dialog;
94import android.app.IActivityController;
95import android.app.IApplicationThread;
96import android.app.IInstrumentationWatcher;
97import android.app.INotificationManager;
98import android.app.IProcessObserver;
99import android.app.IServiceConnection;
100import android.app.IStopUserCallback;
101import android.app.IUiAutomationConnection;
102import android.app.IUserSwitchObserver;
103import android.app.Instrumentation;
104import android.app.Notification;
105import android.app.NotificationManager;
106import android.app.PendingIntent;
107import android.app.backup.IBackupManager;
108import android.content.ActivityNotFoundException;
109import android.content.BroadcastReceiver;
110import android.content.ClipData;
111import android.content.ComponentCallbacks2;
112import android.content.ComponentName;
113import android.content.ContentProvider;
114import android.content.ContentResolver;
115import android.content.Context;
116import android.content.DialogInterface;
117import android.content.IContentProvider;
118import android.content.IIntentReceiver;
119import android.content.IIntentSender;
120import android.content.Intent;
121import android.content.IntentFilter;
122import android.content.IntentSender;
123import android.content.pm.ActivityInfo;
124import android.content.pm.ApplicationInfo;
125import android.content.pm.ConfigurationInfo;
126import android.content.pm.IPackageDataObserver;
127import android.content.pm.IPackageManager;
128import android.content.pm.InstrumentationInfo;
129import android.content.pm.PackageInfo;
130import android.content.pm.PackageManager;
131import android.content.pm.ParceledListSlice;
132import android.content.pm.UserInfo;
133import android.content.pm.PackageManager.NameNotFoundException;
134import android.content.pm.PathPermission;
135import android.content.pm.ProviderInfo;
136import android.content.pm.ResolveInfo;
137import android.content.pm.ServiceInfo;
138import android.content.res.CompatibilityInfo;
139import android.content.res.Configuration;
140import android.graphics.Bitmap;
141import android.net.Proxy;
142import android.net.ProxyInfo;
143import android.net.Uri;
144import android.os.Binder;
145import android.os.Build;
146import android.os.Bundle;
147import android.os.Debug;
148import android.os.DropBoxManager;
149import android.os.Environment;
150import android.os.FactoryTest;
151import android.os.FileObserver;
152import android.os.FileUtils;
153import android.os.Handler;
154import android.os.IBinder;
155import android.os.IPermissionController;
156import android.os.IRemoteCallback;
157import android.os.IUserManager;
158import android.os.Looper;
159import android.os.Message;
160import android.os.Parcel;
161import android.os.ParcelFileDescriptor;
162import android.os.Process;
163import android.os.RemoteCallbackList;
164import android.os.RemoteException;
165import android.os.SELinux;
166import android.os.ServiceManager;
167import android.os.StrictMode;
168import android.os.SystemClock;
169import android.os.SystemProperties;
170import android.os.UpdateLock;
171import android.os.UserHandle;
172import android.provider.Settings;
173import android.text.format.DateUtils;
174import android.text.format.Time;
175import android.util.AtomicFile;
176import android.util.EventLog;
177import android.util.Log;
178import android.util.Pair;
179import android.util.PrintWriterPrinter;
180import android.util.Slog;
181import android.util.SparseArray;
182import android.util.TimeUtils;
183import android.util.Xml;
184import android.view.Gravity;
185import android.view.LayoutInflater;
186import android.view.View;
187import android.view.WindowManager;
188
189import java.io.BufferedInputStream;
190import java.io.BufferedOutputStream;
191import java.io.DataInputStream;
192import java.io.DataOutputStream;
193import java.io.File;
194import java.io.FileDescriptor;
195import java.io.FileInputStream;
196import java.io.FileNotFoundException;
197import java.io.FileOutputStream;
198import java.io.IOException;
199import java.io.InputStreamReader;
200import java.io.PrintWriter;
201import java.io.StringWriter;
202import java.lang.ref.WeakReference;
203import java.util.ArrayList;
204import java.util.Arrays;
205import java.util.Collections;
206import java.util.Comparator;
207import java.util.HashMap;
208import java.util.HashSet;
209import java.util.Iterator;
210import java.util.List;
211import java.util.Locale;
212import java.util.Map;
213import java.util.Set;
214import java.util.concurrent.atomic.AtomicBoolean;
215import java.util.concurrent.atomic.AtomicLong;
216
217public final class ActivityManagerService extends ActivityManagerNative
218        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
219    private static final String USER_DATA_DIR = "/data/user/";
220    static final String TAG = "ActivityManager";
221    static final String TAG_MU = "ActivityManagerServiceMU";
222    static final boolean DEBUG = false;
223    static final boolean localLOGV = DEBUG;
224    static final boolean DEBUG_BACKUP = localLOGV || false;
225    static final boolean DEBUG_BROADCAST = localLOGV || false;
226    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_CLEANUP = localLOGV || false;
229    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
230    static final boolean DEBUG_FOCUS = false;
231    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
232    static final boolean DEBUG_MU = localLOGV || false;
233    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
234    static final boolean DEBUG_LRU = localLOGV || false;
235    static final boolean DEBUG_PAUSE = localLOGV || false;
236    static final boolean DEBUG_POWER = localLOGV || false;
237    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
238    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
239    static final boolean DEBUG_PROCESSES = localLOGV || false;
240    static final boolean DEBUG_PROVIDER = localLOGV || false;
241    static final boolean DEBUG_RESULTS = localLOGV || false;
242    static final boolean DEBUG_SERVICE = localLOGV || false;
243    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
244    static final boolean DEBUG_STACK = localLOGV || false;
245    static final boolean DEBUG_SWITCH = localLOGV || false;
246    static final boolean DEBUG_TASKS = localLOGV || false;
247    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
248    static final boolean DEBUG_TRANSITION = localLOGV || false;
249    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
250    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
251    static final boolean DEBUG_VISBILITY = localLOGV || false;
252    static final boolean DEBUG_PSS = localLOGV || false;
253    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
254    static final boolean VALIDATE_TOKENS = false;
255    static final boolean SHOW_ACTIVITY_START_TIME = true;
256
257    // Control over CPU and battery monitoring.
258    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
259    static final boolean MONITOR_CPU_USAGE = true;
260    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
261    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
262    static final boolean MONITOR_THREAD_CPU_USAGE = false;
263
264    // The flags that are set for all calls we make to the package manager.
265    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
266
267    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
268
269    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
270
271    // Maximum number of recent tasks that we can remember.
272    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
273
274    // Amount of time after a call to stopAppSwitches() during which we will
275    // prevent further untrusted switches from happening.
276    static final long APP_SWITCH_DELAY_TIME = 5*1000;
277
278    // How long we wait for a launched process to attach to the activity manager
279    // before we decide it's never going to come up for real.
280    static final int PROC_START_TIMEOUT = 10*1000;
281
282    // How long we wait for a launched process to attach to the activity manager
283    // before we decide it's never going to come up for real, when the process was
284    // started with a wrapper for instrumentation (such as Valgrind) because it
285    // could take much longer than usual.
286    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
287
288    // How long to wait after going idle before forcing apps to GC.
289    static final int GC_TIMEOUT = 5*1000;
290
291    // The minimum amount of time between successive GC requests for a process.
292    static final int GC_MIN_INTERVAL = 60*1000;
293
294    // The minimum amount of time between successive PSS requests for a process.
295    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
296
297    // The minimum amount of time between successive PSS requests for a process
298    // when the request is due to the memory state being lowered.
299    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
300
301    // The rate at which we check for apps using excessive power -- 15 mins.
302    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
303
304    // The minimum sample duration we will allow before deciding we have
305    // enough data on wake locks to start killing things.
306    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
307
308    // The minimum sample duration we will allow before deciding we have
309    // enough data on CPU usage to start killing things.
310    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
311
312    // How long we allow a receiver to run before giving up on it.
313    static final int BROADCAST_FG_TIMEOUT = 10*1000;
314    static final int BROADCAST_BG_TIMEOUT = 60*1000;
315
316    // How long we wait until we timeout on key dispatching.
317    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
318
319    // How long we wait until we timeout on key dispatching during instrumentation.
320    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
321
322    // Amount of time we wait for observers to handle a user switch before
323    // giving up on them and unfreezing the screen.
324    static final int USER_SWITCH_TIMEOUT = 2*1000;
325
326    // Maximum number of users we allow to be running at a time.
327    static final int MAX_RUNNING_USERS = 3;
328
329    // How long to wait in getAssistContextExtras for the activity and foreground services
330    // to respond with the result.
331    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
332
333    // Maximum number of persisted Uri grants a package is allowed
334    static final int MAX_PERSISTED_URI_GRANTS = 128;
335
336    static final int MY_PID = Process.myPid();
337
338    static final String[] EMPTY_STRING_ARRAY = new String[0];
339
340    // How many bytes to write into the dropbox log before truncating
341    static final int DROPBOX_MAX_SIZE = 256 * 1024;
342
343    /** All system services */
344    SystemServiceManager mSystemServiceManager;
345
346    /** Run all ActivityStacks through this */
347    ActivityStackSupervisor mStackSupervisor;
348
349    public IntentFirewall mIntentFirewall;
350
351    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
352    // default actuion automatically.  Important for devices without direct input
353    // devices.
354    private boolean mShowDialogs = true;
355
356    /**
357     * Description of a request to start a new activity, which has been held
358     * due to app switches being disabled.
359     */
360    static class PendingActivityLaunch {
361        final ActivityRecord r;
362        final ActivityRecord sourceRecord;
363        final int startFlags;
364        final ActivityStack stack;
365
366        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
367                int _startFlags, ActivityStack _stack) {
368            r = _r;
369            sourceRecord = _sourceRecord;
370            startFlags = _startFlags;
371            stack = _stack;
372        }
373    }
374
375    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
376            = new ArrayList<PendingActivityLaunch>();
377
378    BroadcastQueue mFgBroadcastQueue;
379    BroadcastQueue mBgBroadcastQueue;
380    // Convenient for easy iteration over the queues. Foreground is first
381    // so that dispatch of foreground broadcasts gets precedence.
382    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
383
384    BroadcastQueue broadcastQueueForIntent(Intent intent) {
385        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
386        if (DEBUG_BACKGROUND_BROADCAST) {
387            Slog.i(TAG, "Broadcast intent " + intent + " on "
388                    + (isFg ? "foreground" : "background")
389                    + " queue");
390        }
391        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
392    }
393
394    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
395        for (BroadcastQueue queue : mBroadcastQueues) {
396            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
397            if (r != null) {
398                return r;
399            }
400        }
401        return null;
402    }
403
404    /**
405     * Activity we have told the window manager to have key focus.
406     */
407    ActivityRecord mFocusedActivity = null;
408
409    /**
410     * List of intents that were used to start the most recent tasks.
411     */
412    ArrayList<TaskRecord> mRecentTasks;
413
414    public class PendingAssistExtras extends Binder implements Runnable {
415        public final ActivityRecord activity;
416        public boolean haveResult = false;
417        public Bundle result = null;
418        public PendingAssistExtras(ActivityRecord _activity) {
419            activity = _activity;
420        }
421        @Override
422        public void run() {
423            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
424            synchronized (this) {
425                haveResult = true;
426                notifyAll();
427            }
428        }
429    }
430
431    final ArrayList<PendingAssistExtras> mPendingAssistExtras
432            = new ArrayList<PendingAssistExtras>();
433
434    /**
435     * Process management.
436     */
437    final ProcessList mProcessList = new ProcessList();
438
439    /**
440     * All of the applications we currently have running organized by name.
441     * The keys are strings of the application package name (as
442     * returned by the package manager), and the keys are ApplicationRecord
443     * objects.
444     */
445    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
446
447    /**
448     * Tracking long-term execution of processes to look for abuse and other
449     * bad app behavior.
450     */
451    final ProcessStatsService mProcessStats;
452
453    /**
454     * The currently running isolated processes.
455     */
456    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
457
458    /**
459     * Counter for assigning isolated process uids, to avoid frequently reusing the
460     * same ones.
461     */
462    int mNextIsolatedProcessUid = 0;
463
464    /**
465     * The currently running heavy-weight process, if any.
466     */
467    ProcessRecord mHeavyWeightProcess = null;
468
469    /**
470     * The last time that various processes have crashed.
471     */
472    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
473
474    /**
475     * Information about a process that is currently marked as bad.
476     */
477    static final class BadProcessInfo {
478        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
479            this.time = time;
480            this.shortMsg = shortMsg;
481            this.longMsg = longMsg;
482            this.stack = stack;
483        }
484
485        final long time;
486        final String shortMsg;
487        final String longMsg;
488        final String stack;
489    }
490
491    /**
492     * Set of applications that we consider to be bad, and will reject
493     * incoming broadcasts from (which the user has no control over).
494     * Processes are added to this set when they have crashed twice within
495     * a minimum amount of time; they are removed from it when they are
496     * later restarted (hopefully due to some user action).  The value is the
497     * time it was added to the list.
498     */
499    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
500
501    /**
502     * All of the processes we currently have running organized by pid.
503     * The keys are the pid running the application.
504     *
505     * <p>NOTE: This object is protected by its own lock, NOT the global
506     * activity manager lock!
507     */
508    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
509
510    /**
511     * All of the processes that have been forced to be foreground.  The key
512     * is the pid of the caller who requested it (we hold a death
513     * link on it).
514     */
515    abstract class ForegroundToken implements IBinder.DeathRecipient {
516        int pid;
517        IBinder token;
518    }
519    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
520
521    /**
522     * List of records for processes that someone had tried to start before the
523     * system was ready.  We don't start them at that point, but ensure they
524     * are started by the time booting is complete.
525     */
526    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
527
528    /**
529     * List of persistent applications that are in the process
530     * of being started.
531     */
532    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
533
534    /**
535     * Processes that are being forcibly torn down.
536     */
537    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
538
539    /**
540     * List of running applications, sorted by recent usage.
541     * The first entry in the list is the least recently used.
542     */
543    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
544
545    /**
546     * Where in mLruProcesses that the processes hosting activities start.
547     */
548    int mLruProcessActivityStart = 0;
549
550    /**
551     * Where in mLruProcesses that the processes hosting services start.
552     * This is after (lower index) than mLruProcessesActivityStart.
553     */
554    int mLruProcessServiceStart = 0;
555
556    /**
557     * List of processes that should gc as soon as things are idle.
558     */
559    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
560
561    /**
562     * Processes we want to collect PSS data from.
563     */
564    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Last time we requested PSS data of all processes.
568     */
569    long mLastFullPssTime = SystemClock.uptimeMillis();
570
571    /**
572     * This is the process holding what we currently consider to be
573     * the "home" activity.
574     */
575    ProcessRecord mHomeProcess;
576
577    /**
578     * This is the process holding the activity the user last visited that
579     * is in a different process from the one they are currently in.
580     */
581    ProcessRecord mPreviousProcess;
582
583    /**
584     * The time at which the previous process was last visible.
585     */
586    long mPreviousProcessVisibleTime;
587
588    /**
589     * Which uses have been started, so are allowed to run code.
590     */
591    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
592
593    /**
594     * LRU list of history of current users.  Most recently current is at the end.
595     */
596    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
597
598    /**
599     * Constant array of the users that are currently started.
600     */
601    int[] mStartedUserArray = new int[] { 0 };
602
603    /**
604     * Registered observers of the user switching mechanics.
605     */
606    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
607            = new RemoteCallbackList<IUserSwitchObserver>();
608
609    /**
610     * Currently active user switch.
611     */
612    Object mCurUserSwitchCallback;
613
614    /**
615     * Packages that the user has asked to have run in screen size
616     * compatibility mode instead of filling the screen.
617     */
618    final CompatModePackages mCompatModePackages;
619
620    /**
621     * Set of IntentSenderRecord objects that are currently active.
622     */
623    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
624            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
625
626    /**
627     * Fingerprints (hashCode()) of stack traces that we've
628     * already logged DropBox entries for.  Guarded by itself.  If
629     * something (rogue user app) forces this over
630     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
631     */
632    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
633    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
634
635    /**
636     * Strict Mode background batched logging state.
637     *
638     * The string buffer is guarded by itself, and its lock is also
639     * used to determine if another batched write is already
640     * in-flight.
641     */
642    private final StringBuilder mStrictModeBuffer = new StringBuilder();
643
644    /**
645     * Keeps track of all IIntentReceivers that have been registered for
646     * broadcasts.  Hash keys are the receiver IBinder, hash value is
647     * a ReceiverList.
648     */
649    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
650            new HashMap<IBinder, ReceiverList>();
651
652    /**
653     * Resolver for broadcast intents to registered receivers.
654     * Holds BroadcastFilter (subclass of IntentFilter).
655     */
656    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
657            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
658        @Override
659        protected boolean allowFilterResult(
660                BroadcastFilter filter, List<BroadcastFilter> dest) {
661            IBinder target = filter.receiverList.receiver.asBinder();
662            for (int i=dest.size()-1; i>=0; i--) {
663                if (dest.get(i).receiverList.receiver.asBinder() == target) {
664                    return false;
665                }
666            }
667            return true;
668        }
669
670        @Override
671        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
672            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
673                    || userId == filter.owningUserId) {
674                return super.newResult(filter, match, userId);
675            }
676            return null;
677        }
678
679        @Override
680        protected BroadcastFilter[] newArray(int size) {
681            return new BroadcastFilter[size];
682        }
683
684        @Override
685        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
686            return packageName.equals(filter.packageName);
687        }
688    };
689
690    /**
691     * State of all active sticky broadcasts per user.  Keys are the action of the
692     * sticky Intent, values are an ArrayList of all broadcasted intents with
693     * that action (which should usually be one).  The SparseArray is keyed
694     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
695     * for stickies that are sent to all users.
696     */
697    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
698            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
699
700    final ActiveServices mServices;
701
702    /**
703     * Backup/restore process management
704     */
705    String mBackupAppName = null;
706    BackupRecord mBackupTarget = null;
707
708    final ProviderMap mProviderMap;
709
710    /**
711     * List of content providers who have clients waiting for them.  The
712     * application is currently being launched and the provider will be
713     * removed from this list once it is published.
714     */
715    final ArrayList<ContentProviderRecord> mLaunchingProviders
716            = new ArrayList<ContentProviderRecord>();
717
718    /**
719     * File storing persisted {@link #mGrantedUriPermissions}.
720     */
721    private final AtomicFile mGrantFile;
722
723    /** XML constants used in {@link #mGrantFile} */
724    private static final String TAG_URI_GRANTS = "uri-grants";
725    private static final String TAG_URI_GRANT = "uri-grant";
726    private static final String ATTR_USER_HANDLE = "userHandle";
727    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
728    private static final String ATTR_TARGET_USER_ID = "targetUserId";
729    private static final String ATTR_SOURCE_PKG = "sourcePkg";
730    private static final String ATTR_TARGET_PKG = "targetPkg";
731    private static final String ATTR_URI = "uri";
732    private static final String ATTR_MODE_FLAGS = "modeFlags";
733    private static final String ATTR_CREATED_TIME = "createdTime";
734    private static final String ATTR_PREFIX = "prefix";
735
736    /**
737     * Global set of specific {@link Uri} permissions that have been granted.
738     * This optimized lookup structure maps from {@link UriPermission#targetUid}
739     * to {@link UriPermission#uri} to {@link UriPermission}.
740     */
741    @GuardedBy("this")
742    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
743            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
744
745    public static class GrantUri {
746        public final int sourceUserId;
747        public final Uri uri;
748        public boolean prefix;
749
750        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
751            this.sourceUserId = sourceUserId;
752            this.uri = uri;
753            this.prefix = prefix;
754        }
755
756        @Override
757        public int hashCode() {
758            return toString().hashCode();
759        }
760
761        @Override
762        public boolean equals(Object o) {
763            if (o instanceof GrantUri) {
764                GrantUri other = (GrantUri) o;
765                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
766                        && prefix == other.prefix;
767            }
768            return false;
769        }
770
771        @Override
772        public String toString() {
773            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
774            if (prefix) result += " [prefix]";
775            return result;
776        }
777
778        public String toSafeString() {
779            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
780            if (prefix) result += " [prefix]";
781            return result;
782        }
783
784        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
785            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
786                    ContentProvider.getUriWithoutUserId(uri), false);
787        }
788    }
789
790    CoreSettingsObserver mCoreSettingsObserver;
791
792    /**
793     * Thread-local storage used to carry caller permissions over through
794     * indirect content-provider access.
795     */
796    private class Identity {
797        public int pid;
798        public int uid;
799
800        Identity(int _pid, int _uid) {
801            pid = _pid;
802            uid = _uid;
803        }
804    }
805
806    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
807
808    /**
809     * All information we have collected about the runtime performance of
810     * any user id that can impact battery performance.
811     */
812    final BatteryStatsService mBatteryStatsService;
813
814    /**
815     * Information about component usage
816     */
817    final UsageStatsService mUsageStatsService;
818
819    /**
820     * Information about and control over application operations
821     */
822    final AppOpsService mAppOpsService;
823
824    /**
825     * Save recent tasks information across reboots.
826     */
827    final TaskPersister mTaskPersister;
828
829    /**
830     * Current configuration information.  HistoryRecord objects are given
831     * a reference to this object to indicate which configuration they are
832     * currently running in, so this object must be kept immutable.
833     */
834    Configuration mConfiguration = new Configuration();
835
836    /**
837     * Current sequencing integer of the configuration, for skipping old
838     * configurations.
839     */
840    int mConfigurationSeq = 0;
841
842    /**
843     * Hardware-reported OpenGLES version.
844     */
845    final int GL_ES_VERSION;
846
847    /**
848     * List of initialization arguments to pass to all processes when binding applications to them.
849     * For example, references to the commonly used services.
850     */
851    HashMap<String, IBinder> mAppBindArgs;
852
853    /**
854     * Temporary to avoid allocations.  Protected by main lock.
855     */
856    final StringBuilder mStringBuilder = new StringBuilder(256);
857
858    /**
859     * Used to control how we initialize the service.
860     */
861    ComponentName mTopComponent;
862    String mTopAction = Intent.ACTION_MAIN;
863    String mTopData;
864    boolean mProcessesReady = false;
865    boolean mSystemReady = false;
866    boolean mBooting = false;
867    boolean mWaitingUpdate = false;
868    boolean mDidUpdate = false;
869    boolean mOnBattery = false;
870    boolean mLaunchWarningShown = false;
871
872    Context mContext;
873
874    int mFactoryTest;
875
876    boolean mCheckedForSetup;
877
878    /**
879     * The time at which we will allow normal application switches again,
880     * after a call to {@link #stopAppSwitches()}.
881     */
882    long mAppSwitchesAllowedTime;
883
884    /**
885     * This is set to true after the first switch after mAppSwitchesAllowedTime
886     * is set; any switches after that will clear the time.
887     */
888    boolean mDidAppSwitch;
889
890    /**
891     * Last time (in realtime) at which we checked for power usage.
892     */
893    long mLastPowerCheckRealtime;
894
895    /**
896     * Last time (in uptime) at which we checked for power usage.
897     */
898    long mLastPowerCheckUptime;
899
900    /**
901     * Set while we are wanting to sleep, to prevent any
902     * activities from being started/resumed.
903     */
904    private boolean mSleeping = false;
905
906    /**
907     * Set while we are running a voice interaction.  This overrides
908     * sleeping while it is active.
909     */
910    private boolean mRunningVoice = false;
911
912    /**
913     * State of external calls telling us if the device is asleep.
914     */
915    private boolean mWentToSleep = false;
916
917    /**
918     * State of external call telling us if the lock screen is shown.
919     */
920    private boolean mLockScreenShown = false;
921
922    /**
923     * Set if we are shutting down the system, similar to sleeping.
924     */
925    boolean mShuttingDown = false;
926
927    /**
928     * Current sequence id for oom_adj computation traversal.
929     */
930    int mAdjSeq = 0;
931
932    /**
933     * Current sequence id for process LRU updating.
934     */
935    int mLruSeq = 0;
936
937    /**
938     * Keep track of the non-cached/empty process we last found, to help
939     * determine how to distribute cached/empty processes next time.
940     */
941    int mNumNonCachedProcs = 0;
942
943    /**
944     * Keep track of the number of cached hidden procs, to balance oom adj
945     * distribution between those and empty procs.
946     */
947    int mNumCachedHiddenProcs = 0;
948
949    /**
950     * Keep track of the number of service processes we last found, to
951     * determine on the next iteration which should be B services.
952     */
953    int mNumServiceProcs = 0;
954    int mNewNumAServiceProcs = 0;
955    int mNewNumServiceProcs = 0;
956
957    /**
958     * Allow the current computed overall memory level of the system to go down?
959     * This is set to false when we are killing processes for reasons other than
960     * memory management, so that the now smaller process list will not be taken as
961     * an indication that memory is tighter.
962     */
963    boolean mAllowLowerMemLevel = false;
964
965    /**
966     * The last computed memory level, for holding when we are in a state that
967     * processes are going away for other reasons.
968     */
969    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
970
971    /**
972     * The last total number of process we have, to determine if changes actually look
973     * like a shrinking number of process due to lower RAM.
974     */
975    int mLastNumProcesses;
976
977    /**
978     * The uptime of the last time we performed idle maintenance.
979     */
980    long mLastIdleTime = SystemClock.uptimeMillis();
981
982    /**
983     * Total time spent with RAM that has been added in the past since the last idle time.
984     */
985    long mLowRamTimeSinceLastIdle = 0;
986
987    /**
988     * If RAM is currently low, when that horrible situation started.
989     */
990    long mLowRamStartTime = 0;
991
992    /**
993     * For reporting to battery stats the current top application.
994     */
995    private String mCurResumedPackage = null;
996    private int mCurResumedUid = -1;
997
998    /**
999     * For reporting to battery stats the apps currently running foreground
1000     * service.  The ProcessMap is package/uid tuples; each of these contain
1001     * an array of the currently foreground processes.
1002     */
1003    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1004            = new ProcessMap<ArrayList<ProcessRecord>>();
1005
1006    /**
1007     * This is set if we had to do a delayed dexopt of an app before launching
1008     * it, to increase the ANR timeouts in that case.
1009     */
1010    boolean mDidDexOpt;
1011
1012    /**
1013     * Set if the systemServer made a call to enterSafeMode.
1014     */
1015    boolean mSafeMode;
1016
1017    String mDebugApp = null;
1018    boolean mWaitForDebugger = false;
1019    boolean mDebugTransient = false;
1020    String mOrigDebugApp = null;
1021    boolean mOrigWaitForDebugger = false;
1022    boolean mAlwaysFinishActivities = false;
1023    IActivityController mController = null;
1024    String mProfileApp = null;
1025    ProcessRecord mProfileProc = null;
1026    String mProfileFile;
1027    ParcelFileDescriptor mProfileFd;
1028    int mProfileType = 0;
1029    boolean mAutoStopProfiler = false;
1030    String mOpenGlTraceApp = null;
1031
1032    static class ProcessChangeItem {
1033        static final int CHANGE_ACTIVITIES = 1<<0;
1034        static final int CHANGE_PROCESS_STATE = 1<<1;
1035        int changes;
1036        int uid;
1037        int pid;
1038        int processState;
1039        boolean foregroundActivities;
1040    }
1041
1042    final RemoteCallbackList<IProcessObserver> mProcessObservers
1043            = new RemoteCallbackList<IProcessObserver>();
1044    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1045
1046    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1047            = new ArrayList<ProcessChangeItem>();
1048    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1049            = new ArrayList<ProcessChangeItem>();
1050
1051    /**
1052     * Runtime CPU use collection thread.  This object's lock is used to
1053     * protect all related state.
1054     */
1055    final Thread mProcessCpuThread;
1056
1057    /**
1058     * Used to collect process stats when showing not responding dialog.
1059     * Protected by mProcessCpuThread.
1060     */
1061    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1062            MONITOR_THREAD_CPU_USAGE);
1063    final AtomicLong mLastCpuTime = new AtomicLong(0);
1064    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1065
1066    long mLastWriteTime = 0;
1067
1068    /**
1069     * Used to retain an update lock when the foreground activity is in
1070     * immersive mode.
1071     */
1072    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1073
1074    /**
1075     * Set to true after the system has finished booting.
1076     */
1077    boolean mBooted = false;
1078
1079    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1080    int mProcessLimitOverride = -1;
1081
1082    WindowManagerService mWindowManager;
1083
1084    final ActivityThread mSystemThread;
1085
1086    int mCurrentUserId = 0;
1087    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1088    private UserManagerService mUserManager;
1089
1090    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1091        final ProcessRecord mApp;
1092        final int mPid;
1093        final IApplicationThread mAppThread;
1094
1095        AppDeathRecipient(ProcessRecord app, int pid,
1096                IApplicationThread thread) {
1097            if (localLOGV) Slog.v(
1098                TAG, "New death recipient " + this
1099                + " for thread " + thread.asBinder());
1100            mApp = app;
1101            mPid = pid;
1102            mAppThread = thread;
1103        }
1104
1105        @Override
1106        public void binderDied() {
1107            if (localLOGV) Slog.v(
1108                TAG, "Death received in " + this
1109                + " for thread " + mAppThread.asBinder());
1110            synchronized(ActivityManagerService.this) {
1111                appDiedLocked(mApp, mPid, mAppThread);
1112            }
1113        }
1114    }
1115
1116    static final int SHOW_ERROR_MSG = 1;
1117    static final int SHOW_NOT_RESPONDING_MSG = 2;
1118    static final int SHOW_FACTORY_ERROR_MSG = 3;
1119    static final int UPDATE_CONFIGURATION_MSG = 4;
1120    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1121    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1122    static final int SERVICE_TIMEOUT_MSG = 12;
1123    static final int UPDATE_TIME_ZONE = 13;
1124    static final int SHOW_UID_ERROR_MSG = 14;
1125    static final int IM_FEELING_LUCKY_MSG = 15;
1126    static final int PROC_START_TIMEOUT_MSG = 20;
1127    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1128    static final int KILL_APPLICATION_MSG = 22;
1129    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1130    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1131    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1132    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1133    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1134    static final int CLEAR_DNS_CACHE_MSG = 28;
1135    static final int UPDATE_HTTP_PROXY_MSG = 29;
1136    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1137    static final int DISPATCH_PROCESSES_CHANGED = 31;
1138    static final int DISPATCH_PROCESS_DIED = 32;
1139    static final int REPORT_MEM_USAGE_MSG = 33;
1140    static final int REPORT_USER_SWITCH_MSG = 34;
1141    static final int CONTINUE_USER_SWITCH_MSG = 35;
1142    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1143    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1144    static final int PERSIST_URI_GRANTS_MSG = 38;
1145    static final int REQUEST_ALL_PSS_MSG = 39;
1146    static final int START_PROFILES_MSG = 40;
1147    static final int UPDATE_TIME = 41;
1148    static final int SYSTEM_USER_START_MSG = 42;
1149    static final int SYSTEM_USER_CURRENT_MSG = 43;
1150
1151    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1152    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1153    static final int FIRST_COMPAT_MODE_MSG = 300;
1154    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1155
1156    AlertDialog mUidAlert;
1157    CompatModeDialog mCompatModeDialog;
1158    long mLastMemUsageReportTime = 0;
1159
1160    /**
1161     * Flag whether the current user is a "monkey", i.e. whether
1162     * the UI is driven by a UI automation tool.
1163     */
1164    private boolean mUserIsMonkey;
1165
1166    final ServiceThread mHandlerThread;
1167    final MainHandler mHandler;
1168
1169    final class MainHandler extends Handler {
1170        public MainHandler(Looper looper) {
1171            super(looper, null, true);
1172        }
1173
1174        @Override
1175        public void handleMessage(Message msg) {
1176            switch (msg.what) {
1177            case SHOW_ERROR_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1180                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1181                synchronized (ActivityManagerService.this) {
1182                    ProcessRecord proc = (ProcessRecord)data.get("app");
1183                    AppErrorResult res = (AppErrorResult) data.get("result");
1184                    if (proc != null && proc.crashDialog != null) {
1185                        Slog.e(TAG, "App already has crash dialog: " + proc);
1186                        if (res != null) {
1187                            res.set(0);
1188                        }
1189                        return;
1190                    }
1191                    if (!showBackground && UserHandle.getAppId(proc.uid)
1192                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1193                            && proc.pid != MY_PID) {
1194                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1195                        if (res != null) {
1196                            res.set(0);
1197                        }
1198                        return;
1199                    }
1200                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1201                        Dialog d = new AppErrorDialog(mContext,
1202                                ActivityManagerService.this, res, proc);
1203                        d.show();
1204                        proc.crashDialog = d;
1205                    } else {
1206                        // The device is asleep, so just pretend that the user
1207                        // saw a crash dialog and hit "force quit".
1208                        if (res != null) {
1209                            res.set(0);
1210                        }
1211                    }
1212                }
1213
1214                ensureBootCompleted();
1215            } break;
1216            case SHOW_NOT_RESPONDING_MSG: {
1217                synchronized (ActivityManagerService.this) {
1218                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1219                    ProcessRecord proc = (ProcessRecord)data.get("app");
1220                    if (proc != null && proc.anrDialog != null) {
1221                        Slog.e(TAG, "App already has anr dialog: " + proc);
1222                        return;
1223                    }
1224
1225                    Intent intent = new Intent("android.intent.action.ANR");
1226                    if (!mProcessesReady) {
1227                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1228                                | Intent.FLAG_RECEIVER_FOREGROUND);
1229                    }
1230                    broadcastIntentLocked(null, null, intent,
1231                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1232                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1233
1234                    if (mShowDialogs) {
1235                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1236                                mContext, proc, (ActivityRecord)data.get("activity"),
1237                                msg.arg1 != 0);
1238                        d.show();
1239                        proc.anrDialog = d;
1240                    } else {
1241                        // Just kill the app if there is no dialog to be shown.
1242                        killAppAtUsersRequest(proc, null);
1243                    }
1244                }
1245
1246                ensureBootCompleted();
1247            } break;
1248            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1249                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1250                synchronized (ActivityManagerService.this) {
1251                    ProcessRecord proc = (ProcessRecord) data.get("app");
1252                    if (proc == null) {
1253                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1254                        break;
1255                    }
1256                    if (proc.crashDialog != null) {
1257                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1258                        return;
1259                    }
1260                    AppErrorResult res = (AppErrorResult) data.get("result");
1261                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1262                        Dialog d = new StrictModeViolationDialog(mContext,
1263                                ActivityManagerService.this, res, proc);
1264                        d.show();
1265                        proc.crashDialog = d;
1266                    } else {
1267                        // The device is asleep, so just pretend that the user
1268                        // saw a crash dialog and hit "force quit".
1269                        res.set(0);
1270                    }
1271                }
1272                ensureBootCompleted();
1273            } break;
1274            case SHOW_FACTORY_ERROR_MSG: {
1275                Dialog d = new FactoryErrorDialog(
1276                    mContext, msg.getData().getCharSequence("msg"));
1277                d.show();
1278                ensureBootCompleted();
1279            } break;
1280            case UPDATE_CONFIGURATION_MSG: {
1281                final ContentResolver resolver = mContext.getContentResolver();
1282                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1283            } break;
1284            case GC_BACKGROUND_PROCESSES_MSG: {
1285                synchronized (ActivityManagerService.this) {
1286                    performAppGcsIfAppropriateLocked();
1287                }
1288            } break;
1289            case WAIT_FOR_DEBUGGER_MSG: {
1290                synchronized (ActivityManagerService.this) {
1291                    ProcessRecord app = (ProcessRecord)msg.obj;
1292                    if (msg.arg1 != 0) {
1293                        if (!app.waitedForDebugger) {
1294                            Dialog d = new AppWaitingForDebuggerDialog(
1295                                    ActivityManagerService.this,
1296                                    mContext, app);
1297                            app.waitDialog = d;
1298                            app.waitedForDebugger = true;
1299                            d.show();
1300                        }
1301                    } else {
1302                        if (app.waitDialog != null) {
1303                            app.waitDialog.dismiss();
1304                            app.waitDialog = null;
1305                        }
1306                    }
1307                }
1308            } break;
1309            case SERVICE_TIMEOUT_MSG: {
1310                if (mDidDexOpt) {
1311                    mDidDexOpt = false;
1312                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1313                    nmsg.obj = msg.obj;
1314                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1315                    return;
1316                }
1317                mServices.serviceTimeout((ProcessRecord)msg.obj);
1318            } break;
1319            case UPDATE_TIME_ZONE: {
1320                synchronized (ActivityManagerService.this) {
1321                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1322                        ProcessRecord r = mLruProcesses.get(i);
1323                        if (r.thread != null) {
1324                            try {
1325                                r.thread.updateTimeZone();
1326                            } catch (RemoteException ex) {
1327                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1328                            }
1329                        }
1330                    }
1331                }
1332            } break;
1333            case CLEAR_DNS_CACHE_MSG: {
1334                synchronized (ActivityManagerService.this) {
1335                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1336                        ProcessRecord r = mLruProcesses.get(i);
1337                        if (r.thread != null) {
1338                            try {
1339                                r.thread.clearDnsCache();
1340                            } catch (RemoteException ex) {
1341                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1342                            }
1343                        }
1344                    }
1345                }
1346            } break;
1347            case UPDATE_HTTP_PROXY_MSG: {
1348                ProxyInfo proxy = (ProxyInfo)msg.obj;
1349                String host = "";
1350                String port = "";
1351                String exclList = "";
1352                Uri pacFileUrl = Uri.EMPTY;
1353                if (proxy != null) {
1354                    host = proxy.getHost();
1355                    port = Integer.toString(proxy.getPort());
1356                    exclList = proxy.getExclusionListAsString();
1357                    pacFileUrl = proxy.getPacFileUrl();
1358                }
1359                synchronized (ActivityManagerService.this) {
1360                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1361                        ProcessRecord r = mLruProcesses.get(i);
1362                        if (r.thread != null) {
1363                            try {
1364                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1365                            } catch (RemoteException ex) {
1366                                Slog.w(TAG, "Failed to update http proxy for: " +
1367                                        r.info.processName);
1368                            }
1369                        }
1370                    }
1371                }
1372            } break;
1373            case SHOW_UID_ERROR_MSG: {
1374                String title = "System UIDs Inconsistent";
1375                String text = "UIDs on the system are inconsistent, you need to wipe your"
1376                        + " data partition or your device will be unstable.";
1377                Log.e(TAG, title + ": " + text);
1378                if (mShowDialogs) {
1379                    // XXX This is a temporary dialog, no need to localize.
1380                    AlertDialog d = new BaseErrorDialog(mContext);
1381                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1382                    d.setCancelable(false);
1383                    d.setTitle(title);
1384                    d.setMessage(text);
1385                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1386                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1387                    mUidAlert = d;
1388                    d.show();
1389                }
1390            } break;
1391            case IM_FEELING_LUCKY_MSG: {
1392                if (mUidAlert != null) {
1393                    mUidAlert.dismiss();
1394                    mUidAlert = null;
1395                }
1396            } break;
1397            case PROC_START_TIMEOUT_MSG: {
1398                if (mDidDexOpt) {
1399                    mDidDexOpt = false;
1400                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1401                    nmsg.obj = msg.obj;
1402                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1403                    return;
1404                }
1405                ProcessRecord app = (ProcessRecord)msg.obj;
1406                synchronized (ActivityManagerService.this) {
1407                    processStartTimedOutLocked(app);
1408                }
1409            } break;
1410            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1411                synchronized (ActivityManagerService.this) {
1412                    doPendingActivityLaunchesLocked(true);
1413                }
1414            } break;
1415            case KILL_APPLICATION_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    int appid = msg.arg1;
1418                    boolean restart = (msg.arg2 == 1);
1419                    Bundle bundle = (Bundle)msg.obj;
1420                    String pkg = bundle.getString("pkg");
1421                    String reason = bundle.getString("reason");
1422                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1423                            false, UserHandle.USER_ALL, reason);
1424                }
1425            } break;
1426            case FINALIZE_PENDING_INTENT_MSG: {
1427                ((PendingIntentRecord)msg.obj).completeFinalize();
1428            } break;
1429            case POST_HEAVY_NOTIFICATION_MSG: {
1430                INotificationManager inm = NotificationManager.getService();
1431                if (inm == null) {
1432                    return;
1433                }
1434
1435                ActivityRecord root = (ActivityRecord)msg.obj;
1436                ProcessRecord process = root.app;
1437                if (process == null) {
1438                    return;
1439                }
1440
1441                try {
1442                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1443                    String text = mContext.getString(R.string.heavy_weight_notification,
1444                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1445                    Notification notification = new Notification();
1446                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1447                    notification.when = 0;
1448                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1449                    notification.tickerText = text;
1450                    notification.defaults = 0; // please be quiet
1451                    notification.sound = null;
1452                    notification.vibrate = null;
1453                    notification.setLatestEventInfo(context, text,
1454                            mContext.getText(R.string.heavy_weight_notification_detail),
1455                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1456                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1457                                    new UserHandle(root.userId)));
1458
1459                    try {
1460                        int[] outId = new int[1];
1461                        inm.enqueueNotificationWithTag("android", "android", null,
1462                                R.string.heavy_weight_notification,
1463                                notification, outId, root.userId);
1464                    } catch (RuntimeException e) {
1465                        Slog.w(ActivityManagerService.TAG,
1466                                "Error showing notification for heavy-weight app", e);
1467                    } catch (RemoteException e) {
1468                    }
1469                } catch (NameNotFoundException e) {
1470                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1471                }
1472            } break;
1473            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1474                INotificationManager inm = NotificationManager.getService();
1475                if (inm == null) {
1476                    return;
1477                }
1478                try {
1479                    inm.cancelNotificationWithTag("android", null,
1480                            R.string.heavy_weight_notification,  msg.arg1);
1481                } catch (RuntimeException e) {
1482                    Slog.w(ActivityManagerService.TAG,
1483                            "Error canceling notification for service", e);
1484                } catch (RemoteException e) {
1485                }
1486            } break;
1487            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1488                synchronized (ActivityManagerService.this) {
1489                    checkExcessivePowerUsageLocked(true);
1490                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1491                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1492                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1493                }
1494            } break;
1495            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1496                synchronized (ActivityManagerService.this) {
1497                    ActivityRecord ar = (ActivityRecord)msg.obj;
1498                    if (mCompatModeDialog != null) {
1499                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1500                                ar.info.applicationInfo.packageName)) {
1501                            return;
1502                        }
1503                        mCompatModeDialog.dismiss();
1504                        mCompatModeDialog = null;
1505                    }
1506                    if (ar != null && false) {
1507                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1508                                ar.packageName)) {
1509                            int mode = mCompatModePackages.computeCompatModeLocked(
1510                                    ar.info.applicationInfo);
1511                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1512                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1513                                mCompatModeDialog = new CompatModeDialog(
1514                                        ActivityManagerService.this, mContext,
1515                                        ar.info.applicationInfo);
1516                                mCompatModeDialog.show();
1517                            }
1518                        }
1519                    }
1520                }
1521                break;
1522            }
1523            case DISPATCH_PROCESSES_CHANGED: {
1524                dispatchProcessesChanged();
1525                break;
1526            }
1527            case DISPATCH_PROCESS_DIED: {
1528                final int pid = msg.arg1;
1529                final int uid = msg.arg2;
1530                dispatchProcessDied(pid, uid);
1531                break;
1532            }
1533            case REPORT_MEM_USAGE_MSG: {
1534                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1535                Thread thread = new Thread() {
1536                    @Override public void run() {
1537                        final SparseArray<ProcessMemInfo> infoMap
1538                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1539                        for (int i=0, N=memInfos.size(); i<N; i++) {
1540                            ProcessMemInfo mi = memInfos.get(i);
1541                            infoMap.put(mi.pid, mi);
1542                        }
1543                        updateCpuStatsNow();
1544                        synchronized (mProcessCpuThread) {
1545                            final int N = mProcessCpuTracker.countStats();
1546                            for (int i=0; i<N; i++) {
1547                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1548                                if (st.vsize > 0) {
1549                                    long pss = Debug.getPss(st.pid, null);
1550                                    if (pss > 0) {
1551                                        if (infoMap.indexOfKey(st.pid) < 0) {
1552                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1553                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1554                                            mi.pss = pss;
1555                                            memInfos.add(mi);
1556                                        }
1557                                    }
1558                                }
1559                            }
1560                        }
1561
1562                        long totalPss = 0;
1563                        for (int i=0, N=memInfos.size(); i<N; i++) {
1564                            ProcessMemInfo mi = memInfos.get(i);
1565                            if (mi.pss == 0) {
1566                                mi.pss = Debug.getPss(mi.pid, null);
1567                            }
1568                            totalPss += mi.pss;
1569                        }
1570                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1571                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1572                                if (lhs.oomAdj != rhs.oomAdj) {
1573                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1574                                }
1575                                if (lhs.pss != rhs.pss) {
1576                                    return lhs.pss < rhs.pss ? 1 : -1;
1577                                }
1578                                return 0;
1579                            }
1580                        });
1581
1582                        StringBuilder tag = new StringBuilder(128);
1583                        StringBuilder stack = new StringBuilder(128);
1584                        tag.append("Low on memory -- ");
1585                        appendMemBucket(tag, totalPss, "total", false);
1586                        appendMemBucket(stack, totalPss, "total", true);
1587
1588                        StringBuilder logBuilder = new StringBuilder(1024);
1589                        logBuilder.append("Low on memory:\n");
1590
1591                        boolean firstLine = true;
1592                        int lastOomAdj = Integer.MIN_VALUE;
1593                        for (int i=0, N=memInfos.size(); i<N; i++) {
1594                            ProcessMemInfo mi = memInfos.get(i);
1595
1596                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1597                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1598                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1599                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1600                                if (lastOomAdj != mi.oomAdj) {
1601                                    lastOomAdj = mi.oomAdj;
1602                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1603                                        tag.append(" / ");
1604                                    }
1605                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1606                                        if (firstLine) {
1607                                            stack.append(":");
1608                                            firstLine = false;
1609                                        }
1610                                        stack.append("\n\t at ");
1611                                    } else {
1612                                        stack.append("$");
1613                                    }
1614                                } else {
1615                                    tag.append(" ");
1616                                    stack.append("$");
1617                                }
1618                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1619                                    appendMemBucket(tag, mi.pss, mi.name, false);
1620                                }
1621                                appendMemBucket(stack, mi.pss, mi.name, true);
1622                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1623                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1624                                    stack.append("(");
1625                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1626                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1627                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1628                                            stack.append(":");
1629                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1630                                        }
1631                                    }
1632                                    stack.append(")");
1633                                }
1634                            }
1635
1636                            logBuilder.append("  ");
1637                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1638                            logBuilder.append(' ');
1639                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1640                            logBuilder.append(' ');
1641                            ProcessList.appendRamKb(logBuilder, mi.pss);
1642                            logBuilder.append(" kB: ");
1643                            logBuilder.append(mi.name);
1644                            logBuilder.append(" (");
1645                            logBuilder.append(mi.pid);
1646                            logBuilder.append(") ");
1647                            logBuilder.append(mi.adjType);
1648                            logBuilder.append('\n');
1649                            if (mi.adjReason != null) {
1650                                logBuilder.append("                      ");
1651                                logBuilder.append(mi.adjReason);
1652                                logBuilder.append('\n');
1653                            }
1654                        }
1655
1656                        logBuilder.append("           ");
1657                        ProcessList.appendRamKb(logBuilder, totalPss);
1658                        logBuilder.append(" kB: TOTAL\n");
1659
1660                        long[] infos = new long[Debug.MEMINFO_COUNT];
1661                        Debug.getMemInfo(infos);
1662                        logBuilder.append("  MemInfo: ");
1663                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1664                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1665                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1666                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1667                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1668                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1669                            logBuilder.append("  ZRAM: ");
1670                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1671                            logBuilder.append(" kB RAM, ");
1672                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1673                            logBuilder.append(" kB swap total, ");
1674                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1675                            logBuilder.append(" kB swap free\n");
1676                        }
1677                        Slog.i(TAG, logBuilder.toString());
1678
1679                        StringBuilder dropBuilder = new StringBuilder(1024);
1680                        /*
1681                        StringWriter oomSw = new StringWriter();
1682                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1683                        StringWriter catSw = new StringWriter();
1684                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1685                        String[] emptyArgs = new String[] { };
1686                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1687                        oomPw.flush();
1688                        String oomString = oomSw.toString();
1689                        */
1690                        dropBuilder.append(stack);
1691                        dropBuilder.append('\n');
1692                        dropBuilder.append('\n');
1693                        dropBuilder.append(logBuilder);
1694                        dropBuilder.append('\n');
1695                        /*
1696                        dropBuilder.append(oomString);
1697                        dropBuilder.append('\n');
1698                        */
1699                        StringWriter catSw = new StringWriter();
1700                        synchronized (ActivityManagerService.this) {
1701                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                            String[] emptyArgs = new String[] { };
1703                            catPw.println();
1704                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1705                            catPw.println();
1706                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1707                                    false, false, null);
1708                            catPw.println();
1709                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1710                            catPw.flush();
1711                        }
1712                        dropBuilder.append(catSw.toString());
1713                        addErrorToDropBox("lowmem", null, "system_server", null,
1714                                null, tag.toString(), dropBuilder.toString(), null, null);
1715                        //Slog.i(TAG, "Sent to dropbox:");
1716                        //Slog.i(TAG, dropBuilder.toString());
1717                        synchronized (ActivityManagerService.this) {
1718                            long now = SystemClock.uptimeMillis();
1719                            if (mLastMemUsageReportTime < now) {
1720                                mLastMemUsageReportTime = now;
1721                            }
1722                        }
1723                    }
1724                };
1725                thread.start();
1726                break;
1727            }
1728            case REPORT_USER_SWITCH_MSG: {
1729                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1730                break;
1731            }
1732            case CONTINUE_USER_SWITCH_MSG: {
1733                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1734                break;
1735            }
1736            case USER_SWITCH_TIMEOUT_MSG: {
1737                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1738                break;
1739            }
1740            case IMMERSIVE_MODE_LOCK_MSG: {
1741                final boolean nextState = (msg.arg1 != 0);
1742                if (mUpdateLock.isHeld() != nextState) {
1743                    if (DEBUG_IMMERSIVE) {
1744                        final ActivityRecord r = (ActivityRecord) msg.obj;
1745                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1746                    }
1747                    if (nextState) {
1748                        mUpdateLock.acquire();
1749                    } else {
1750                        mUpdateLock.release();
1751                    }
1752                }
1753                break;
1754            }
1755            case PERSIST_URI_GRANTS_MSG: {
1756                writeGrantedUriPermissions();
1757                break;
1758            }
1759            case REQUEST_ALL_PSS_MSG: {
1760                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1761                break;
1762            }
1763            case START_PROFILES_MSG: {
1764                synchronized (ActivityManagerService.this) {
1765                    startProfilesLocked();
1766                }
1767                break;
1768            }
1769            case UPDATE_TIME: {
1770                synchronized (ActivityManagerService.this) {
1771                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1772                        ProcessRecord r = mLruProcesses.get(i);
1773                        if (r.thread != null) {
1774                            try {
1775                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1776                            } catch (RemoteException ex) {
1777                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1778                            }
1779                        }
1780                    }
1781                }
1782                break;
1783            }
1784            case SYSTEM_USER_START_MSG: {
1785                mSystemServiceManager.startUser(msg.arg1);
1786                break;
1787            }
1788            case SYSTEM_USER_CURRENT_MSG: {
1789                mSystemServiceManager.switchUser(msg.arg1);
1790                break;
1791            }
1792            }
1793        }
1794    };
1795
1796    static final int COLLECT_PSS_BG_MSG = 1;
1797
1798    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1799        @Override
1800        public void handleMessage(Message msg) {
1801            switch (msg.what) {
1802            case COLLECT_PSS_BG_MSG: {
1803                int i=0, num=0;
1804                long start = SystemClock.uptimeMillis();
1805                long[] tmp = new long[1];
1806                do {
1807                    ProcessRecord proc;
1808                    int procState;
1809                    int pid;
1810                    synchronized (ActivityManagerService.this) {
1811                        if (i >= mPendingPssProcesses.size()) {
1812                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1813                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1814                            mPendingPssProcesses.clear();
1815                            return;
1816                        }
1817                        proc = mPendingPssProcesses.get(i);
1818                        procState = proc.pssProcState;
1819                        if (proc.thread != null && procState == proc.setProcState) {
1820                            pid = proc.pid;
1821                        } else {
1822                            proc = null;
1823                            pid = 0;
1824                        }
1825                        i++;
1826                    }
1827                    if (proc != null) {
1828                        long pss = Debug.getPss(pid, tmp);
1829                        synchronized (ActivityManagerService.this) {
1830                            if (proc.thread != null && proc.setProcState == procState
1831                                    && proc.pid == pid) {
1832                                num++;
1833                                proc.lastPssTime = SystemClock.uptimeMillis();
1834                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1835                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1836                                        + ": " + pss + " lastPss=" + proc.lastPss
1837                                        + " state=" + ProcessList.makeProcStateString(procState));
1838                                if (proc.initialIdlePss == 0) {
1839                                    proc.initialIdlePss = pss;
1840                                }
1841                                proc.lastPss = pss;
1842                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1843                                    proc.lastCachedPss = pss;
1844                                }
1845                            }
1846                        }
1847                    }
1848                } while (true);
1849            }
1850            }
1851        }
1852    };
1853
1854    /**
1855     * Monitor for package changes and update our internal state.
1856     */
1857    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1858        @Override
1859        public void onPackageRemoved(String packageName, int uid) {
1860            // Remove all tasks with activities in the specified package from the list of recent tasks
1861            synchronized (ActivityManagerService.this) {
1862                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1863                    TaskRecord tr = mRecentTasks.get(i);
1864                    ComponentName cn = tr.intent.getComponent();
1865                    if (cn != null && cn.getPackageName().equals(packageName)) {
1866                        // If the package name matches, remove the task and kill the process
1867                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1868                    }
1869                }
1870            }
1871        }
1872
1873        @Override
1874        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1875            onPackageModified(packageName);
1876            return true;
1877        }
1878
1879        @Override
1880        public void onPackageModified(String packageName) {
1881            final PackageManager pm = mContext.getPackageManager();
1882            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1883                    new ArrayList<Pair<Intent, Integer>>();
1884            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1885            // Copy the list of recent tasks so that we don't hold onto the lock on
1886            // ActivityManagerService for long periods while checking if components exist.
1887            synchronized (ActivityManagerService.this) {
1888                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1889                    TaskRecord tr = mRecentTasks.get(i);
1890                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1891                }
1892            }
1893            // Check the recent tasks and filter out all tasks with components that no longer exist.
1894            Intent tmpI = new Intent();
1895            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1896                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1897                ComponentName cn = p.first.getComponent();
1898                if (cn != null && cn.getPackageName().equals(packageName)) {
1899                    try {
1900                        // Add the task to the list to remove if the component no longer exists
1901                        tmpI.setComponent(cn);
1902                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1903                            tasksToRemove.add(p.second);
1904                        }
1905                    } catch (Exception e) {}
1906                }
1907            }
1908            // Prune all the tasks with removed components from the list of recent tasks
1909            synchronized (ActivityManagerService.this) {
1910                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1911                    // Remove the task but don't kill the process (since other components in that
1912                    // package may still be running and in the background)
1913                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1914                }
1915            }
1916        }
1917
1918        @Override
1919        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1920            // Force stop the specified packages
1921            if (packages != null) {
1922                for (String pkg : packages) {
1923                    synchronized (ActivityManagerService.this) {
1924                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1925                                "finished booting")) {
1926                            return true;
1927                        }
1928                    }
1929                }
1930            }
1931            return false;
1932        }
1933    };
1934
1935    public void setSystemProcess() {
1936        try {
1937            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1938            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1939            ServiceManager.addService("meminfo", new MemBinder(this));
1940            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1941            ServiceManager.addService("dbinfo", new DbBinder(this));
1942            if (MONITOR_CPU_USAGE) {
1943                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1944            }
1945            ServiceManager.addService("permission", new PermissionController(this));
1946
1947            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1948                    "android", STOCK_PM_FLAGS);
1949            mSystemThread.installSystemApplicationInfo(info);
1950
1951            synchronized (this) {
1952                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1953                app.persistent = true;
1954                app.pid = MY_PID;
1955                app.maxAdj = ProcessList.SYSTEM_ADJ;
1956                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1957                mProcessNames.put(app.processName, app.uid, app);
1958                synchronized (mPidsSelfLocked) {
1959                    mPidsSelfLocked.put(app.pid, app);
1960                }
1961                updateLruProcessLocked(app, false, null);
1962                updateOomAdjLocked();
1963            }
1964        } catch (PackageManager.NameNotFoundException e) {
1965            throw new RuntimeException(
1966                    "Unable to find android system package", e);
1967        }
1968    }
1969
1970    public void setWindowManager(WindowManagerService wm) {
1971        mWindowManager = wm;
1972        mStackSupervisor.setWindowManager(wm);
1973    }
1974
1975    public void startObservingNativeCrashes() {
1976        final NativeCrashListener ncl = new NativeCrashListener(this);
1977        ncl.start();
1978    }
1979
1980    public IAppOpsService getAppOpsService() {
1981        return mAppOpsService;
1982    }
1983
1984    static class MemBinder extends Binder {
1985        ActivityManagerService mActivityManagerService;
1986        MemBinder(ActivityManagerService activityManagerService) {
1987            mActivityManagerService = activityManagerService;
1988        }
1989
1990        @Override
1991        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1992            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1993                    != PackageManager.PERMISSION_GRANTED) {
1994                pw.println("Permission Denial: can't dump meminfo from from pid="
1995                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1996                        + " without permission " + android.Manifest.permission.DUMP);
1997                return;
1998            }
1999
2000            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2001        }
2002    }
2003
2004    static class GraphicsBinder extends Binder {
2005        ActivityManagerService mActivityManagerService;
2006        GraphicsBinder(ActivityManagerService activityManagerService) {
2007            mActivityManagerService = activityManagerService;
2008        }
2009
2010        @Override
2011        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2012            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2013                    != PackageManager.PERMISSION_GRANTED) {
2014                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2015                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2016                        + " without permission " + android.Manifest.permission.DUMP);
2017                return;
2018            }
2019
2020            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2021        }
2022    }
2023
2024    static class DbBinder extends Binder {
2025        ActivityManagerService mActivityManagerService;
2026        DbBinder(ActivityManagerService activityManagerService) {
2027            mActivityManagerService = activityManagerService;
2028        }
2029
2030        @Override
2031        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2032            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2033                    != PackageManager.PERMISSION_GRANTED) {
2034                pw.println("Permission Denial: can't dump dbinfo from from pid="
2035                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2036                        + " without permission " + android.Manifest.permission.DUMP);
2037                return;
2038            }
2039
2040            mActivityManagerService.dumpDbInfo(fd, pw, args);
2041        }
2042    }
2043
2044    static class CpuBinder extends Binder {
2045        ActivityManagerService mActivityManagerService;
2046        CpuBinder(ActivityManagerService activityManagerService) {
2047            mActivityManagerService = activityManagerService;
2048        }
2049
2050        @Override
2051        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2052            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2053                    != PackageManager.PERMISSION_GRANTED) {
2054                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2055                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2056                        + " without permission " + android.Manifest.permission.DUMP);
2057                return;
2058            }
2059
2060            synchronized (mActivityManagerService.mProcessCpuThread) {
2061                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2062                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2063                        SystemClock.uptimeMillis()));
2064            }
2065        }
2066    }
2067
2068    public static final class Lifecycle extends SystemService {
2069        private final ActivityManagerService mService;
2070
2071        public Lifecycle(Context context) {
2072            super(context);
2073            mService = new ActivityManagerService(context);
2074        }
2075
2076        @Override
2077        public void onStart() {
2078            mService.start();
2079        }
2080
2081        public ActivityManagerService getService() {
2082            return mService;
2083        }
2084    }
2085
2086    // Note: This method is invoked on the main thread but may need to attach various
2087    // handlers to other threads.  So take care to be explicit about the looper.
2088    public ActivityManagerService(Context systemContext) {
2089        mContext = systemContext;
2090        mFactoryTest = FactoryTest.getMode();
2091        mSystemThread = ActivityThread.currentActivityThread();
2092
2093        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2094
2095        mHandlerThread = new ServiceThread(TAG,
2096                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2097        mHandlerThread.start();
2098        mHandler = new MainHandler(mHandlerThread.getLooper());
2099
2100        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2101                "foreground", BROADCAST_FG_TIMEOUT, false);
2102        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2103                "background", BROADCAST_BG_TIMEOUT, true);
2104        mBroadcastQueues[0] = mFgBroadcastQueue;
2105        mBroadcastQueues[1] = mBgBroadcastQueue;
2106
2107        mServices = new ActiveServices(this);
2108        mProviderMap = new ProviderMap(this);
2109
2110        // TODO: Move creation of battery stats service outside of activity manager service.
2111        File dataDir = Environment.getDataDirectory();
2112        File systemDir = new File(dataDir, "system");
2113        systemDir.mkdirs();
2114        mBatteryStatsService = new BatteryStatsService(new File(
2115                systemDir, "batterystats.bin").toString(), mHandler);
2116        mBatteryStatsService.getActiveStatistics().readLocked();
2117        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2118        mOnBattery = DEBUG_POWER ? true
2119                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2120        mBatteryStatsService.getActiveStatistics().setCallback(this);
2121
2122        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2123
2124        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2125        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2126
2127        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2128
2129        // User 0 is the first and only user that runs at boot.
2130        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2131        mUserLru.add(Integer.valueOf(0));
2132        updateStartedUserArrayLocked();
2133
2134        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2135            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2136
2137        mConfiguration.setToDefaults();
2138        mConfiguration.setLocale(Locale.getDefault());
2139
2140        mConfigurationSeq = mConfiguration.seq = 1;
2141        mProcessCpuTracker.init();
2142
2143        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2144        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2145        mStackSupervisor = new ActivityStackSupervisor(this);
2146        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2147
2148        mProcessCpuThread = new Thread("CpuTracker") {
2149            @Override
2150            public void run() {
2151                while (true) {
2152                    try {
2153                        try {
2154                            synchronized(this) {
2155                                final long now = SystemClock.uptimeMillis();
2156                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2157                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2158                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2159                                //        + ", write delay=" + nextWriteDelay);
2160                                if (nextWriteDelay < nextCpuDelay) {
2161                                    nextCpuDelay = nextWriteDelay;
2162                                }
2163                                if (nextCpuDelay > 0) {
2164                                    mProcessCpuMutexFree.set(true);
2165                                    this.wait(nextCpuDelay);
2166                                }
2167                            }
2168                        } catch (InterruptedException e) {
2169                        }
2170                        updateCpuStatsNow();
2171                    } catch (Exception e) {
2172                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2173                    }
2174                }
2175            }
2176        };
2177
2178        Watchdog.getInstance().addMonitor(this);
2179        Watchdog.getInstance().addThread(mHandler);
2180    }
2181
2182    public void setSystemServiceManager(SystemServiceManager mgr) {
2183        mSystemServiceManager = mgr;
2184    }
2185
2186    private void start() {
2187        mProcessCpuThread.start();
2188
2189        mBatteryStatsService.publish(mContext);
2190        mUsageStatsService.publish(mContext);
2191        mAppOpsService.publish(mContext);
2192
2193        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2194    }
2195
2196    @Override
2197    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2198            throws RemoteException {
2199        if (code == SYSPROPS_TRANSACTION) {
2200            // We need to tell all apps about the system property change.
2201            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2202            synchronized(this) {
2203                final int NP = mProcessNames.getMap().size();
2204                for (int ip=0; ip<NP; ip++) {
2205                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2206                    final int NA = apps.size();
2207                    for (int ia=0; ia<NA; ia++) {
2208                        ProcessRecord app = apps.valueAt(ia);
2209                        if (app.thread != null) {
2210                            procs.add(app.thread.asBinder());
2211                        }
2212                    }
2213                }
2214            }
2215
2216            int N = procs.size();
2217            for (int i=0; i<N; i++) {
2218                Parcel data2 = Parcel.obtain();
2219                try {
2220                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2221                } catch (RemoteException e) {
2222                }
2223                data2.recycle();
2224            }
2225        }
2226        try {
2227            return super.onTransact(code, data, reply, flags);
2228        } catch (RuntimeException e) {
2229            // The activity manager only throws security exceptions, so let's
2230            // log all others.
2231            if (!(e instanceof SecurityException)) {
2232                Slog.wtf(TAG, "Activity Manager Crash", e);
2233            }
2234            throw e;
2235        }
2236    }
2237
2238    void updateCpuStats() {
2239        final long now = SystemClock.uptimeMillis();
2240        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2241            return;
2242        }
2243        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2244            synchronized (mProcessCpuThread) {
2245                mProcessCpuThread.notify();
2246            }
2247        }
2248    }
2249
2250    void updateCpuStatsNow() {
2251        synchronized (mProcessCpuThread) {
2252            mProcessCpuMutexFree.set(false);
2253            final long now = SystemClock.uptimeMillis();
2254            boolean haveNewCpuStats = false;
2255
2256            if (MONITOR_CPU_USAGE &&
2257                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2258                mLastCpuTime.set(now);
2259                haveNewCpuStats = true;
2260                mProcessCpuTracker.update();
2261                //Slog.i(TAG, mProcessCpu.printCurrentState());
2262                //Slog.i(TAG, "Total CPU usage: "
2263                //        + mProcessCpu.getTotalCpuPercent() + "%");
2264
2265                // Slog the cpu usage if the property is set.
2266                if ("true".equals(SystemProperties.get("events.cpu"))) {
2267                    int user = mProcessCpuTracker.getLastUserTime();
2268                    int system = mProcessCpuTracker.getLastSystemTime();
2269                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2270                    int irq = mProcessCpuTracker.getLastIrqTime();
2271                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2272                    int idle = mProcessCpuTracker.getLastIdleTime();
2273
2274                    int total = user + system + iowait + irq + softIrq + idle;
2275                    if (total == 0) total = 1;
2276
2277                    EventLog.writeEvent(EventLogTags.CPU,
2278                            ((user+system+iowait+irq+softIrq) * 100) / total,
2279                            (user * 100) / total,
2280                            (system * 100) / total,
2281                            (iowait * 100) / total,
2282                            (irq * 100) / total,
2283                            (softIrq * 100) / total);
2284                }
2285            }
2286
2287            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2288            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2289            synchronized(bstats) {
2290                synchronized(mPidsSelfLocked) {
2291                    if (haveNewCpuStats) {
2292                        if (mOnBattery) {
2293                            int perc = bstats.startAddingCpuLocked();
2294                            int totalUTime = 0;
2295                            int totalSTime = 0;
2296                            final int N = mProcessCpuTracker.countStats();
2297                            for (int i=0; i<N; i++) {
2298                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2299                                if (!st.working) {
2300                                    continue;
2301                                }
2302                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2303                                int otherUTime = (st.rel_utime*perc)/100;
2304                                int otherSTime = (st.rel_stime*perc)/100;
2305                                totalUTime += otherUTime;
2306                                totalSTime += otherSTime;
2307                                if (pr != null) {
2308                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2309                                    if (ps == null || !ps.isActive()) {
2310                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2311                                                pr.info.uid, pr.processName);
2312                                    }
2313                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2314                                            st.rel_stime-otherSTime);
2315                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2316                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2317                                } else {
2318                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2319                                    if (ps == null || !ps.isActive()) {
2320                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2321                                                bstats.mapUid(st.uid), st.name);
2322                                    }
2323                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2324                                            st.rel_stime-otherSTime);
2325                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2326                                }
2327                            }
2328                            bstats.finishAddingCpuLocked(perc, totalUTime,
2329                                    totalSTime, cpuSpeedTimes);
2330                        }
2331                    }
2332                }
2333
2334                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2335                    mLastWriteTime = now;
2336                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2337                }
2338            }
2339        }
2340    }
2341
2342    @Override
2343    public void batteryNeedsCpuUpdate() {
2344        updateCpuStatsNow();
2345    }
2346
2347    @Override
2348    public void batteryPowerChanged(boolean onBattery) {
2349        // When plugging in, update the CPU stats first before changing
2350        // the plug state.
2351        updateCpuStatsNow();
2352        synchronized (this) {
2353            synchronized(mPidsSelfLocked) {
2354                mOnBattery = DEBUG_POWER ? true : onBattery;
2355            }
2356        }
2357    }
2358
2359    /**
2360     * Initialize the application bind args. These are passed to each
2361     * process when the bindApplication() IPC is sent to the process. They're
2362     * lazily setup to make sure the services are running when they're asked for.
2363     */
2364    private HashMap<String, IBinder> getCommonServicesLocked() {
2365        if (mAppBindArgs == null) {
2366            mAppBindArgs = new HashMap<String, IBinder>();
2367
2368            // Setup the application init args
2369            mAppBindArgs.put("package", ServiceManager.getService("package"));
2370            mAppBindArgs.put("window", ServiceManager.getService("window"));
2371            mAppBindArgs.put(Context.ALARM_SERVICE,
2372                    ServiceManager.getService(Context.ALARM_SERVICE));
2373        }
2374        return mAppBindArgs;
2375    }
2376
2377    final void setFocusedActivityLocked(ActivityRecord r) {
2378        if (mFocusedActivity != r) {
2379            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2380            mFocusedActivity = r;
2381            if (r.task != null && r.task.voiceInteractor != null) {
2382                startRunningVoiceLocked();
2383            } else {
2384                finishRunningVoiceLocked();
2385            }
2386            mStackSupervisor.setFocusedStack(r);
2387            if (r != null) {
2388                mWindowManager.setFocusedApp(r.appToken, true);
2389            }
2390            applyUpdateLockStateLocked(r);
2391        }
2392    }
2393
2394    final void clearFocusedActivity(ActivityRecord r) {
2395        if (mFocusedActivity == r) {
2396            mFocusedActivity = null;
2397        }
2398    }
2399
2400    @Override
2401    public void setFocusedStack(int stackId) {
2402        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2403        synchronized (ActivityManagerService.this) {
2404            ActivityStack stack = mStackSupervisor.getStack(stackId);
2405            if (stack != null) {
2406                ActivityRecord r = stack.topRunningActivityLocked(null);
2407                if (r != null) {
2408                    setFocusedActivityLocked(r);
2409                }
2410            }
2411        }
2412    }
2413
2414    @Override
2415    public void notifyActivityDrawn(IBinder token) {
2416        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2417        synchronized (this) {
2418            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2419            if (r != null) {
2420                r.task.stack.notifyActivityDrawnLocked(r);
2421            }
2422        }
2423    }
2424
2425    final void applyUpdateLockStateLocked(ActivityRecord r) {
2426        // Modifications to the UpdateLock state are done on our handler, outside
2427        // the activity manager's locks.  The new state is determined based on the
2428        // state *now* of the relevant activity record.  The object is passed to
2429        // the handler solely for logging detail, not to be consulted/modified.
2430        final boolean nextState = r != null && r.immersive;
2431        mHandler.sendMessage(
2432                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2433    }
2434
2435    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2436        Message msg = Message.obtain();
2437        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2438        msg.obj = r.task.askedCompatMode ? null : r;
2439        mHandler.sendMessage(msg);
2440    }
2441
2442    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2443            String what, Object obj, ProcessRecord srcApp) {
2444        app.lastActivityTime = now;
2445
2446        if (app.activities.size() > 0) {
2447            // Don't want to touch dependent processes that are hosting activities.
2448            return index;
2449        }
2450
2451        int lrui = mLruProcesses.lastIndexOf(app);
2452        if (lrui < 0) {
2453            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2454                    + what + " " + obj + " from " + srcApp);
2455            return index;
2456        }
2457
2458        if (lrui >= index) {
2459            // Don't want to cause this to move dependent processes *back* in the
2460            // list as if they were less frequently used.
2461            return index;
2462        }
2463
2464        if (lrui >= mLruProcessActivityStart) {
2465            // Don't want to touch dependent processes that are hosting activities.
2466            return index;
2467        }
2468
2469        mLruProcesses.remove(lrui);
2470        if (index > 0) {
2471            index--;
2472        }
2473        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2474                + " in LRU list: " + app);
2475        mLruProcesses.add(index, app);
2476        return index;
2477    }
2478
2479    final void removeLruProcessLocked(ProcessRecord app) {
2480        int lrui = mLruProcesses.lastIndexOf(app);
2481        if (lrui >= 0) {
2482            if (lrui <= mLruProcessActivityStart) {
2483                mLruProcessActivityStart--;
2484            }
2485            if (lrui <= mLruProcessServiceStart) {
2486                mLruProcessServiceStart--;
2487            }
2488            mLruProcesses.remove(lrui);
2489        }
2490    }
2491
2492    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2493            ProcessRecord client) {
2494        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2495                || app.treatLikeActivity;
2496        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2497        if (!activityChange && hasActivity) {
2498            // The process has activities, so we are only allowing activity-based adjustments
2499            // to move it.  It should be kept in the front of the list with other
2500            // processes that have activities, and we don't want those to change their
2501            // order except due to activity operations.
2502            return;
2503        }
2504
2505        mLruSeq++;
2506        final long now = SystemClock.uptimeMillis();
2507        app.lastActivityTime = now;
2508
2509        // First a quick reject: if the app is already at the position we will
2510        // put it, then there is nothing to do.
2511        if (hasActivity) {
2512            final int N = mLruProcesses.size();
2513            if (N > 0 && mLruProcesses.get(N-1) == app) {
2514                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2515                return;
2516            }
2517        } else {
2518            if (mLruProcessServiceStart > 0
2519                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2520                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2521                return;
2522            }
2523        }
2524
2525        int lrui = mLruProcesses.lastIndexOf(app);
2526
2527        if (app.persistent && lrui >= 0) {
2528            // We don't care about the position of persistent processes, as long as
2529            // they are in the list.
2530            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2531            return;
2532        }
2533
2534        /* In progress: compute new position first, so we can avoid doing work
2535           if the process is not actually going to move.  Not yet working.
2536        int addIndex;
2537        int nextIndex;
2538        boolean inActivity = false, inService = false;
2539        if (hasActivity) {
2540            // Process has activities, put it at the very tipsy-top.
2541            addIndex = mLruProcesses.size();
2542            nextIndex = mLruProcessServiceStart;
2543            inActivity = true;
2544        } else if (hasService) {
2545            // Process has services, put it at the top of the service list.
2546            addIndex = mLruProcessActivityStart;
2547            nextIndex = mLruProcessServiceStart;
2548            inActivity = true;
2549            inService = true;
2550        } else  {
2551            // Process not otherwise of interest, it goes to the top of the non-service area.
2552            addIndex = mLruProcessServiceStart;
2553            if (client != null) {
2554                int clientIndex = mLruProcesses.lastIndexOf(client);
2555                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2556                        + app);
2557                if (clientIndex >= 0 && addIndex > clientIndex) {
2558                    addIndex = clientIndex;
2559                }
2560            }
2561            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2562        }
2563
2564        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2565                + mLruProcessActivityStart + "): " + app);
2566        */
2567
2568        if (lrui >= 0) {
2569            if (lrui < mLruProcessActivityStart) {
2570                mLruProcessActivityStart--;
2571            }
2572            if (lrui < mLruProcessServiceStart) {
2573                mLruProcessServiceStart--;
2574            }
2575            /*
2576            if (addIndex > lrui) {
2577                addIndex--;
2578            }
2579            if (nextIndex > lrui) {
2580                nextIndex--;
2581            }
2582            */
2583            mLruProcesses.remove(lrui);
2584        }
2585
2586        /*
2587        mLruProcesses.add(addIndex, app);
2588        if (inActivity) {
2589            mLruProcessActivityStart++;
2590        }
2591        if (inService) {
2592            mLruProcessActivityStart++;
2593        }
2594        */
2595
2596        int nextIndex;
2597        if (hasActivity) {
2598            final int N = mLruProcesses.size();
2599            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2600                // Process doesn't have activities, but has clients with
2601                // activities...  move it up, but one below the top (the top
2602                // should always have a real activity).
2603                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2604                mLruProcesses.add(N-1, app);
2605                // To keep it from spamming the LRU list (by making a bunch of clients),
2606                // we will push down any other entries owned by the app.
2607                final int uid = app.info.uid;
2608                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2609                    ProcessRecord subProc = mLruProcesses.get(i);
2610                    if (subProc.info.uid == uid) {
2611                        // We want to push this one down the list.  If the process after
2612                        // it is for the same uid, however, don't do so, because we don't
2613                        // want them internally to be re-ordered.
2614                        if (mLruProcesses.get(i-1).info.uid != uid) {
2615                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2616                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2617                            ProcessRecord tmp = mLruProcesses.get(i);
2618                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2619                            mLruProcesses.set(i-1, tmp);
2620                            i--;
2621                        }
2622                    } else {
2623                        // A gap, we can stop here.
2624                        break;
2625                    }
2626                }
2627            } else {
2628                // Process has activities, put it at the very tipsy-top.
2629                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2630                mLruProcesses.add(app);
2631            }
2632            nextIndex = mLruProcessServiceStart;
2633        } else if (hasService) {
2634            // Process has services, put it at the top of the service list.
2635            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2636            mLruProcesses.add(mLruProcessActivityStart, app);
2637            nextIndex = mLruProcessServiceStart;
2638            mLruProcessActivityStart++;
2639        } else  {
2640            // Process not otherwise of interest, it goes to the top of the non-service area.
2641            int index = mLruProcessServiceStart;
2642            if (client != null) {
2643                // If there is a client, don't allow the process to be moved up higher
2644                // in the list than that client.
2645                int clientIndex = mLruProcesses.lastIndexOf(client);
2646                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2647                        + " when updating " + app);
2648                if (clientIndex <= lrui) {
2649                    // Don't allow the client index restriction to push it down farther in the
2650                    // list than it already is.
2651                    clientIndex = lrui;
2652                }
2653                if (clientIndex >= 0 && index > clientIndex) {
2654                    index = clientIndex;
2655                }
2656            }
2657            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2658            mLruProcesses.add(index, app);
2659            nextIndex = index-1;
2660            mLruProcessActivityStart++;
2661            mLruProcessServiceStart++;
2662        }
2663
2664        // If the app is currently using a content provider or service,
2665        // bump those processes as well.
2666        for (int j=app.connections.size()-1; j>=0; j--) {
2667            ConnectionRecord cr = app.connections.valueAt(j);
2668            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2669                    && cr.binding.service.app != null
2670                    && cr.binding.service.app.lruSeq != mLruSeq
2671                    && !cr.binding.service.app.persistent) {
2672                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2673                        "service connection", cr, app);
2674            }
2675        }
2676        for (int j=app.conProviders.size()-1; j>=0; j--) {
2677            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2678            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2679                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2680                        "provider reference", cpr, app);
2681            }
2682        }
2683    }
2684
2685    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2686        if (uid == Process.SYSTEM_UID) {
2687            // The system gets to run in any process.  If there are multiple
2688            // processes with the same uid, just pick the first (this
2689            // should never happen).
2690            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2691            if (procs == null) return null;
2692            final int N = procs.size();
2693            for (int i = 0; i < N; i++) {
2694                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2695            }
2696        }
2697        ProcessRecord proc = mProcessNames.get(processName, uid);
2698        if (false && proc != null && !keepIfLarge
2699                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2700                && proc.lastCachedPss >= 4000) {
2701            // Turn this condition on to cause killing to happen regularly, for testing.
2702            if (proc.baseProcessTracker != null) {
2703                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2704            }
2705            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2706                    + "k from cached");
2707        } else if (proc != null && !keepIfLarge
2708                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2709                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2710            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2711            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2712                if (proc.baseProcessTracker != null) {
2713                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2714                }
2715                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2716                        + "k from cached");
2717            }
2718        }
2719        return proc;
2720    }
2721
2722    void ensurePackageDexOpt(String packageName) {
2723        IPackageManager pm = AppGlobals.getPackageManager();
2724        try {
2725            if (pm.performDexOpt(packageName)) {
2726                mDidDexOpt = true;
2727            }
2728        } catch (RemoteException e) {
2729        }
2730    }
2731
2732    boolean isNextTransitionForward() {
2733        int transit = mWindowManager.getPendingAppTransition();
2734        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2735                || transit == AppTransition.TRANSIT_TASK_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2737    }
2738
2739    final ProcessRecord startProcessLocked(String processName,
2740            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2741            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2742            boolean isolated, boolean keepIfLarge) {
2743        ProcessRecord app;
2744        if (!isolated) {
2745            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2746        } else {
2747            // If this is an isolated process, it can't re-use an existing process.
2748            app = null;
2749        }
2750        // We don't have to do anything more if:
2751        // (1) There is an existing application record; and
2752        // (2) The caller doesn't think it is dead, OR there is no thread
2753        //     object attached to it so we know it couldn't have crashed; and
2754        // (3) There is a pid assigned to it, so it is either starting or
2755        //     already running.
2756        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2757                + " app=" + app + " knownToBeDead=" + knownToBeDead
2758                + " thread=" + (app != null ? app.thread : null)
2759                + " pid=" + (app != null ? app.pid : -1));
2760        if (app != null && app.pid > 0) {
2761            if (!knownToBeDead || app.thread == null) {
2762                // We already have the app running, or are waiting for it to
2763                // come up (we have a pid but not yet its thread), so keep it.
2764                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2765                // If this is a new package in the process, add the package to the list
2766                app.addPackage(info.packageName, mProcessStats);
2767                return app;
2768            }
2769
2770            // An application record is attached to a previous process,
2771            // clean it up now.
2772            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2773            handleAppDiedLocked(app, true, true);
2774        }
2775
2776        String hostingNameStr = hostingName != null
2777                ? hostingName.flattenToShortString() : null;
2778
2779        if (!isolated) {
2780            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2781                // If we are in the background, then check to see if this process
2782                // is bad.  If so, we will just silently fail.
2783                if (mBadProcesses.get(info.processName, info.uid) != null) {
2784                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2785                            + "/" + info.processName);
2786                    return null;
2787                }
2788            } else {
2789                // When the user is explicitly starting a process, then clear its
2790                // crash count so that we won't make it bad until they see at
2791                // least one crash dialog again, and make the process good again
2792                // if it had been bad.
2793                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2794                        + "/" + info.processName);
2795                mProcessCrashTimes.remove(info.processName, info.uid);
2796                if (mBadProcesses.get(info.processName, info.uid) != null) {
2797                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2798                            UserHandle.getUserId(info.uid), info.uid,
2799                            info.processName);
2800                    mBadProcesses.remove(info.processName, info.uid);
2801                    if (app != null) {
2802                        app.bad = false;
2803                    }
2804                }
2805            }
2806        }
2807
2808        if (app == null) {
2809            app = newProcessRecordLocked(info, processName, isolated);
2810            if (app == null) {
2811                Slog.w(TAG, "Failed making new process record for "
2812                        + processName + "/" + info.uid + " isolated=" + isolated);
2813                return null;
2814            }
2815            mProcessNames.put(processName, app.uid, app);
2816            if (isolated) {
2817                mIsolatedProcesses.put(app.uid, app);
2818            }
2819        } else {
2820            // If this is a new package in the process, add the package to the list
2821            app.addPackage(info.packageName, mProcessStats);
2822        }
2823
2824        // If the system is not ready yet, then hold off on starting this
2825        // process until it is.
2826        if (!mProcessesReady
2827                && !isAllowedWhileBooting(info)
2828                && !allowWhileBooting) {
2829            if (!mProcessesOnHold.contains(app)) {
2830                mProcessesOnHold.add(app);
2831            }
2832            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2833            return app;
2834        }
2835
2836        startProcessLocked(app, hostingType, hostingNameStr);
2837        return (app.pid != 0) ? app : null;
2838    }
2839
2840    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2841        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2842    }
2843
2844    private final void startProcessLocked(ProcessRecord app,
2845            String hostingType, String hostingNameStr) {
2846        if (app.pid > 0 && app.pid != MY_PID) {
2847            synchronized (mPidsSelfLocked) {
2848                mPidsSelfLocked.remove(app.pid);
2849                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2850            }
2851            app.setPid(0);
2852        }
2853
2854        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2855                "startProcessLocked removing on hold: " + app);
2856        mProcessesOnHold.remove(app);
2857
2858        updateCpuStats();
2859
2860        try {
2861            int uid = app.uid;
2862
2863            int[] gids = null;
2864            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2865            if (!app.isolated) {
2866                int[] permGids = null;
2867                try {
2868                    final PackageManager pm = mContext.getPackageManager();
2869                    permGids = pm.getPackageGids(app.info.packageName);
2870
2871                    if (Environment.isExternalStorageEmulated()) {
2872                        if (pm.checkPermission(
2873                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2874                                app.info.packageName) == PERMISSION_GRANTED) {
2875                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2876                        } else {
2877                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2878                        }
2879                    }
2880                } catch (PackageManager.NameNotFoundException e) {
2881                    Slog.w(TAG, "Unable to retrieve gids", e);
2882                }
2883
2884                /*
2885                 * Add shared application GID so applications can share some
2886                 * resources like shared libraries
2887                 */
2888                if (permGids == null) {
2889                    gids = new int[1];
2890                } else {
2891                    gids = new int[permGids.length + 1];
2892                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2893                }
2894                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2895            }
2896            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2897                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2898                        && mTopComponent != null
2899                        && app.processName.equals(mTopComponent.getPackageName())) {
2900                    uid = 0;
2901                }
2902                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2903                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2904                    uid = 0;
2905                }
2906            }
2907            int debugFlags = 0;
2908            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2909                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2910                // Also turn on CheckJNI for debuggable apps. It's quite
2911                // awkward to turn on otherwise.
2912                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2913            }
2914            // Run the app in safe mode if its manifest requests so or the
2915            // system is booted in safe mode.
2916            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2917                mSafeMode == true) {
2918                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2919            }
2920            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2921                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2922            }
2923            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2924                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2925            }
2926            if ("1".equals(SystemProperties.get("debug.assert"))) {
2927                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2928            }
2929
2930            String requiredAbi = app.info.cpuAbi;
2931            if (requiredAbi == null) {
2932                requiredAbi = Build.SUPPORTED_ABIS[0];
2933            }
2934
2935            // Start the process.  It will either succeed and return a result containing
2936            // the PID of the new process, or else throw a RuntimeException.
2937            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2938                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2939                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2940
2941            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2942            synchronized (bs) {
2943                if (bs.isOnBattery()) {
2944                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2945                }
2946            }
2947
2948            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2949                    UserHandle.getUserId(uid), startResult.pid, uid,
2950                    app.processName, hostingType,
2951                    hostingNameStr != null ? hostingNameStr : "");
2952
2953            if (app.persistent) {
2954                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2955            }
2956
2957            StringBuilder buf = mStringBuilder;
2958            buf.setLength(0);
2959            buf.append("Start proc ");
2960            buf.append(app.processName);
2961            buf.append(" for ");
2962            buf.append(hostingType);
2963            if (hostingNameStr != null) {
2964                buf.append(" ");
2965                buf.append(hostingNameStr);
2966            }
2967            buf.append(": pid=");
2968            buf.append(startResult.pid);
2969            buf.append(" uid=");
2970            buf.append(uid);
2971            buf.append(" gids={");
2972            if (gids != null) {
2973                for (int gi=0; gi<gids.length; gi++) {
2974                    if (gi != 0) buf.append(", ");
2975                    buf.append(gids[gi]);
2976
2977                }
2978            }
2979            buf.append("}");
2980            Slog.i(TAG, buf.toString());
2981            app.setPid(startResult.pid);
2982            app.usingWrapper = startResult.usingWrapper;
2983            app.removed = false;
2984            synchronized (mPidsSelfLocked) {
2985                this.mPidsSelfLocked.put(startResult.pid, app);
2986                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2987                msg.obj = app;
2988                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2989                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2990            }
2991            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2992                    app.processName, app.info.uid);
2993            if (app.isolated) {
2994                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2995            }
2996        } catch (RuntimeException e) {
2997            // XXX do better error recovery.
2998            app.setPid(0);
2999            Slog.e(TAG, "Failure starting process " + app.processName, e);
3000        }
3001    }
3002
3003    void updateUsageStats(ActivityRecord component, boolean resumed) {
3004        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3005        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3006        if (resumed) {
3007            mUsageStatsService.noteResumeComponent(component.realActivity);
3008            synchronized (stats) {
3009                stats.noteActivityResumedLocked(component.app.uid);
3010            }
3011        } else {
3012            mUsageStatsService.notePauseComponent(component.realActivity);
3013            synchronized (stats) {
3014                stats.noteActivityPausedLocked(component.app.uid);
3015            }
3016        }
3017    }
3018
3019    Intent getHomeIntent() {
3020        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3021        intent.setComponent(mTopComponent);
3022        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3023            intent.addCategory(Intent.CATEGORY_HOME);
3024        }
3025        return intent;
3026    }
3027
3028    boolean startHomeActivityLocked(int userId) {
3029        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3030                && mTopAction == null) {
3031            // We are running in factory test mode, but unable to find
3032            // the factory test app, so just sit around displaying the
3033            // error message and don't try to start anything.
3034            return false;
3035        }
3036        Intent intent = getHomeIntent();
3037        ActivityInfo aInfo =
3038            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3039        if (aInfo != null) {
3040            intent.setComponent(new ComponentName(
3041                    aInfo.applicationInfo.packageName, aInfo.name));
3042            // Don't do this if the home app is currently being
3043            // instrumented.
3044            aInfo = new ActivityInfo(aInfo);
3045            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3046            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3047                    aInfo.applicationInfo.uid, true);
3048            if (app == null || app.instrumentationClass == null) {
3049                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3050                mStackSupervisor.startHomeActivity(intent, aInfo);
3051            }
3052        }
3053
3054        return true;
3055    }
3056
3057    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3058        ActivityInfo ai = null;
3059        ComponentName comp = intent.getComponent();
3060        try {
3061            if (comp != null) {
3062                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3063            } else {
3064                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3065                        intent,
3066                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3067                            flags, userId);
3068
3069                if (info != null) {
3070                    ai = info.activityInfo;
3071                }
3072            }
3073        } catch (RemoteException e) {
3074            // ignore
3075        }
3076
3077        return ai;
3078    }
3079
3080    /**
3081     * Starts the "new version setup screen" if appropriate.
3082     */
3083    void startSetupActivityLocked() {
3084        // Only do this once per boot.
3085        if (mCheckedForSetup) {
3086            return;
3087        }
3088
3089        // We will show this screen if the current one is a different
3090        // version than the last one shown, and we are not running in
3091        // low-level factory test mode.
3092        final ContentResolver resolver = mContext.getContentResolver();
3093        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3094                Settings.Global.getInt(resolver,
3095                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3096            mCheckedForSetup = true;
3097
3098            // See if we should be showing the platform update setup UI.
3099            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3100            List<ResolveInfo> ris = mContext.getPackageManager()
3101                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3102
3103            // We don't allow third party apps to replace this.
3104            ResolveInfo ri = null;
3105            for (int i=0; ris != null && i<ris.size(); i++) {
3106                if ((ris.get(i).activityInfo.applicationInfo.flags
3107                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3108                    ri = ris.get(i);
3109                    break;
3110                }
3111            }
3112
3113            if (ri != null) {
3114                String vers = ri.activityInfo.metaData != null
3115                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3116                        : null;
3117                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3118                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3119                            Intent.METADATA_SETUP_VERSION);
3120                }
3121                String lastVers = Settings.Secure.getString(
3122                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3123                if (vers != null && !vers.equals(lastVers)) {
3124                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3125                    intent.setComponent(new ComponentName(
3126                            ri.activityInfo.packageName, ri.activityInfo.name));
3127                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3128                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3129                }
3130            }
3131        }
3132    }
3133
3134    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3135        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3136    }
3137
3138    void enforceNotIsolatedCaller(String caller) {
3139        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3140            throw new SecurityException("Isolated process not allowed to call " + caller);
3141        }
3142    }
3143
3144    @Override
3145    public int getFrontActivityScreenCompatMode() {
3146        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3147        synchronized (this) {
3148            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3149        }
3150    }
3151
3152    @Override
3153    public void setFrontActivityScreenCompatMode(int mode) {
3154        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3155                "setFrontActivityScreenCompatMode");
3156        synchronized (this) {
3157            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3158        }
3159    }
3160
3161    @Override
3162    public int getPackageScreenCompatMode(String packageName) {
3163        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3164        synchronized (this) {
3165            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3166        }
3167    }
3168
3169    @Override
3170    public void setPackageScreenCompatMode(String packageName, int mode) {
3171        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3172                "setPackageScreenCompatMode");
3173        synchronized (this) {
3174            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3175        }
3176    }
3177
3178    @Override
3179    public boolean getPackageAskScreenCompat(String packageName) {
3180        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3181        synchronized (this) {
3182            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3183        }
3184    }
3185
3186    @Override
3187    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3188        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3189                "setPackageAskScreenCompat");
3190        synchronized (this) {
3191            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3192        }
3193    }
3194
3195    private void dispatchProcessesChanged() {
3196        int N;
3197        synchronized (this) {
3198            N = mPendingProcessChanges.size();
3199            if (mActiveProcessChanges.length < N) {
3200                mActiveProcessChanges = new ProcessChangeItem[N];
3201            }
3202            mPendingProcessChanges.toArray(mActiveProcessChanges);
3203            mAvailProcessChanges.addAll(mPendingProcessChanges);
3204            mPendingProcessChanges.clear();
3205            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3206        }
3207
3208        int i = mProcessObservers.beginBroadcast();
3209        while (i > 0) {
3210            i--;
3211            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3212            if (observer != null) {
3213                try {
3214                    for (int j=0; j<N; j++) {
3215                        ProcessChangeItem item = mActiveProcessChanges[j];
3216                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3217                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3218                                    + item.pid + " uid=" + item.uid + ": "
3219                                    + item.foregroundActivities);
3220                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3221                                    item.foregroundActivities);
3222                        }
3223                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3224                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3225                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3226                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3227                        }
3228                    }
3229                } catch (RemoteException e) {
3230                }
3231            }
3232        }
3233        mProcessObservers.finishBroadcast();
3234    }
3235
3236    private void dispatchProcessDied(int pid, int uid) {
3237        int i = mProcessObservers.beginBroadcast();
3238        while (i > 0) {
3239            i--;
3240            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3241            if (observer != null) {
3242                try {
3243                    observer.onProcessDied(pid, uid);
3244                } catch (RemoteException e) {
3245                }
3246            }
3247        }
3248        mProcessObservers.finishBroadcast();
3249    }
3250
3251    final void doPendingActivityLaunchesLocked(boolean doResume) {
3252        final int N = mPendingActivityLaunches.size();
3253        if (N <= 0) {
3254            return;
3255        }
3256        for (int i=0; i<N; i++) {
3257            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3258            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3259                    doResume && i == (N-1), null);
3260        }
3261        mPendingActivityLaunches.clear();
3262    }
3263
3264    @Override
3265    public final int startActivity(IApplicationThread caller, String callingPackage,
3266            Intent intent, String resolvedType, IBinder resultTo,
3267            String resultWho, int requestCode, int startFlags,
3268            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3269        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3270                resultWho, requestCode,
3271                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3272    }
3273
3274    @Override
3275    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3276            Intent intent, String resolvedType, IBinder resultTo,
3277            String resultWho, int requestCode, int startFlags,
3278            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3279        enforceNotIsolatedCaller("startActivity");
3280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3281                false, true, "startActivity", null);
3282        // TODO: Switch to user app stacks here.
3283        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3284                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3285                null, null, options, userId, null);
3286    }
3287
3288    @Override
3289    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3290            Intent intent, String resolvedType, IBinder resultTo,
3291            String resultWho, int requestCode, int startFlags, String profileFile,
3292            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3293        enforceNotIsolatedCaller("startActivityAndWait");
3294        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3295                false, true, "startActivityAndWait", null);
3296        WaitResult res = new WaitResult();
3297        // TODO: Switch to user app stacks here.
3298        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3299                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3300                res, null, options, UserHandle.getCallingUserId(), null);
3301        return res;
3302    }
3303
3304    @Override
3305    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3306            Intent intent, String resolvedType, IBinder resultTo,
3307            String resultWho, int requestCode, int startFlags, Configuration config,
3308            Bundle options, int userId) {
3309        enforceNotIsolatedCaller("startActivityWithConfig");
3310        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3311                false, true, "startActivityWithConfig", null);
3312        // TODO: Switch to user app stacks here.
3313        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3314                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3315                null, null, null, config, options, userId, null);
3316        return ret;
3317    }
3318
3319    @Override
3320    public int startActivityIntentSender(IApplicationThread caller,
3321            IntentSender intent, Intent fillInIntent, String resolvedType,
3322            IBinder resultTo, String resultWho, int requestCode,
3323            int flagsMask, int flagsValues, Bundle options) {
3324        enforceNotIsolatedCaller("startActivityIntentSender");
3325        // Refuse possible leaked file descriptors
3326        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3327            throw new IllegalArgumentException("File descriptors passed in Intent");
3328        }
3329
3330        IIntentSender sender = intent.getTarget();
3331        if (!(sender instanceof PendingIntentRecord)) {
3332            throw new IllegalArgumentException("Bad PendingIntent object");
3333        }
3334
3335        PendingIntentRecord pir = (PendingIntentRecord)sender;
3336
3337        synchronized (this) {
3338            // If this is coming from the currently resumed activity, it is
3339            // effectively saying that app switches are allowed at this point.
3340            final ActivityStack stack = getFocusedStack();
3341            if (stack.mResumedActivity != null &&
3342                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3343                mAppSwitchesAllowedTime = 0;
3344            }
3345        }
3346        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3347                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3348        return ret;
3349    }
3350
3351    @Override
3352    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3353            Intent intent, String resolvedType, IVoiceInteractionSession session,
3354            IVoiceInteractor interactor, int startFlags, String profileFile,
3355            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3356        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3357                != PackageManager.PERMISSION_GRANTED) {
3358            String msg = "Permission Denial: startVoiceActivity() from pid="
3359                    + Binder.getCallingPid()
3360                    + ", uid=" + Binder.getCallingUid()
3361                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3362            Slog.w(TAG, msg);
3363            throw new SecurityException(msg);
3364        }
3365        if (session == null || interactor == null) {
3366            throw new NullPointerException("null session or interactor");
3367        }
3368        userId = handleIncomingUser(callingPid, callingUid, userId,
3369                false, true, "startVoiceActivity", null);
3370        // TODO: Switch to user app stacks here.
3371        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3372                resolvedType, session, interactor, null, null, 0, startFlags,
3373                profileFile, profileFd, null, null, options, userId, null);
3374    }
3375
3376    @Override
3377    public boolean startNextMatchingActivity(IBinder callingActivity,
3378            Intent intent, Bundle options) {
3379        // Refuse possible leaked file descriptors
3380        if (intent != null && intent.hasFileDescriptors() == true) {
3381            throw new IllegalArgumentException("File descriptors passed in Intent");
3382        }
3383
3384        synchronized (this) {
3385            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3386            if (r == null) {
3387                ActivityOptions.abort(options);
3388                return false;
3389            }
3390            if (r.app == null || r.app.thread == null) {
3391                // The caller is not running...  d'oh!
3392                ActivityOptions.abort(options);
3393                return false;
3394            }
3395            intent = new Intent(intent);
3396            // The caller is not allowed to change the data.
3397            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3398            // And we are resetting to find the next component...
3399            intent.setComponent(null);
3400
3401            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3402
3403            ActivityInfo aInfo = null;
3404            try {
3405                List<ResolveInfo> resolves =
3406                    AppGlobals.getPackageManager().queryIntentActivities(
3407                            intent, r.resolvedType,
3408                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3409                            UserHandle.getCallingUserId());
3410
3411                // Look for the original activity in the list...
3412                final int N = resolves != null ? resolves.size() : 0;
3413                for (int i=0; i<N; i++) {
3414                    ResolveInfo rInfo = resolves.get(i);
3415                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3416                            && rInfo.activityInfo.name.equals(r.info.name)) {
3417                        // We found the current one...  the next matching is
3418                        // after it.
3419                        i++;
3420                        if (i<N) {
3421                            aInfo = resolves.get(i).activityInfo;
3422                        }
3423                        if (debug) {
3424                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3425                                    + "/" + r.info.name);
3426                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3427                                    + "/" + aInfo.name);
3428                        }
3429                        break;
3430                    }
3431                }
3432            } catch (RemoteException e) {
3433            }
3434
3435            if (aInfo == null) {
3436                // Nobody who is next!
3437                ActivityOptions.abort(options);
3438                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3439                return false;
3440            }
3441
3442            intent.setComponent(new ComponentName(
3443                    aInfo.applicationInfo.packageName, aInfo.name));
3444            intent.setFlags(intent.getFlags()&~(
3445                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3446                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3447                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3448                    Intent.FLAG_ACTIVITY_NEW_TASK));
3449
3450            // Okay now we need to start the new activity, replacing the
3451            // currently running activity.  This is a little tricky because
3452            // we want to start the new one as if the current one is finished,
3453            // but not finish the current one first so that there is no flicker.
3454            // And thus...
3455            final boolean wasFinishing = r.finishing;
3456            r.finishing = true;
3457
3458            // Propagate reply information over to the new activity.
3459            final ActivityRecord resultTo = r.resultTo;
3460            final String resultWho = r.resultWho;
3461            final int requestCode = r.requestCode;
3462            r.resultTo = null;
3463            if (resultTo != null) {
3464                resultTo.removeResultsLocked(r, resultWho, requestCode);
3465            }
3466
3467            final long origId = Binder.clearCallingIdentity();
3468            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3469                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3470                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3471                    options, false, null, null);
3472            Binder.restoreCallingIdentity(origId);
3473
3474            r.finishing = wasFinishing;
3475            if (res != ActivityManager.START_SUCCESS) {
3476                return false;
3477            }
3478            return true;
3479        }
3480    }
3481
3482    final int startActivityInPackage(int uid, String callingPackage,
3483            Intent intent, String resolvedType, IBinder resultTo,
3484            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3485                    IActivityContainer container) {
3486
3487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3488                false, true, "startActivityInPackage", null);
3489
3490        // TODO: Switch to user app stacks here.
3491        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3492                null, null, resultTo, resultWho, requestCode, startFlags,
3493                null, null, null, null, options, userId, container);
3494        return ret;
3495    }
3496
3497    @Override
3498    public final int startActivities(IApplicationThread caller, String callingPackage,
3499            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3500            int userId) {
3501        enforceNotIsolatedCaller("startActivities");
3502        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3503                false, true, "startActivity", null);
3504        // TODO: Switch to user app stacks here.
3505        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3506                resolvedTypes, resultTo, options, userId);
3507        return ret;
3508    }
3509
3510    final int startActivitiesInPackage(int uid, String callingPackage,
3511            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3512            Bundle options, int userId) {
3513
3514        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3515                false, true, "startActivityInPackage", null);
3516        // TODO: Switch to user app stacks here.
3517        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3518                resultTo, options, userId);
3519        return ret;
3520    }
3521
3522    final void addRecentTaskLocked(TaskRecord task) {
3523        int N = mRecentTasks.size();
3524        // Quick case: check if the top-most recent task is the same.
3525        if (N > 0 && mRecentTasks.get(0) == task) {
3526            return;
3527        }
3528        // Another quick case: never add voice sessions.
3529        if (task.voiceSession != null) {
3530            return;
3531        }
3532        // Remove any existing entries that are the same kind of task.
3533        final Intent intent = task.intent;
3534        final boolean document = intent != null && intent.isDocument();
3535        for (int i=0; i<N; i++) {
3536            TaskRecord tr = mRecentTasks.get(i);
3537            if (task != tr) {
3538                if (task.userId != tr.userId) {
3539                    continue;
3540                }
3541                final Intent trIntent = tr.intent;
3542                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3543                    (intent == null || !intent.filterEquals(trIntent))) {
3544                    continue;
3545                }
3546                if (document || trIntent != null && trIntent.isDocument()) {
3547                    // Document tasks do not match other tasks.
3548                    continue;
3549                }
3550            }
3551
3552            // Either task and tr are the same or, their affinities match or their intents match
3553            // and neither of them is a document.
3554            tr.disposeThumbnail();
3555            mRecentTasks.remove(i);
3556            i--;
3557            N--;
3558            if (task.intent == null) {
3559                // If the new recent task we are adding is not fully
3560                // specified, then replace it with the existing recent task.
3561                task = tr;
3562            }
3563        }
3564        if (N >= MAX_RECENT_TASKS) {
3565            mRecentTasks.remove(N-1).disposeThumbnail();
3566        }
3567        mRecentTasks.add(0, task);
3568    }
3569
3570    @Override
3571    public void reportActivityFullyDrawn(IBinder token) {
3572        synchronized (this) {
3573            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3574            if (r == null) {
3575                return;
3576            }
3577            r.reportFullyDrawnLocked();
3578        }
3579    }
3580
3581    @Override
3582    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3583        synchronized (this) {
3584            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3585            if (r == null) {
3586                return;
3587            }
3588            final long origId = Binder.clearCallingIdentity();
3589            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3590            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3591                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3592            if (config != null) {
3593                r.frozenBeforeDestroy = true;
3594                if (!updateConfigurationLocked(config, r, false, false)) {
3595                    mStackSupervisor.resumeTopActivitiesLocked();
3596                }
3597            }
3598            Binder.restoreCallingIdentity(origId);
3599        }
3600    }
3601
3602    @Override
3603    public int getRequestedOrientation(IBinder token) {
3604        synchronized (this) {
3605            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3606            if (r == null) {
3607                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3608            }
3609            return mWindowManager.getAppOrientation(r.appToken);
3610        }
3611    }
3612
3613    /**
3614     * This is the internal entry point for handling Activity.finish().
3615     *
3616     * @param token The Binder token referencing the Activity we want to finish.
3617     * @param resultCode Result code, if any, from this Activity.
3618     * @param resultData Result data (Intent), if any, from this Activity.
3619     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3620     *            the root Activity in the task.
3621     *
3622     * @return Returns true if the activity successfully finished, or false if it is still running.
3623     */
3624    @Override
3625    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3626            boolean finishTask) {
3627        // Refuse possible leaked file descriptors
3628        if (resultData != null && resultData.hasFileDescriptors() == true) {
3629            throw new IllegalArgumentException("File descriptors passed in Intent");
3630        }
3631
3632        synchronized(this) {
3633            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3634            if (r == null) {
3635                return true;
3636            }
3637            // Keep track of the root activity of the task before we finish it
3638            TaskRecord tr = r.task;
3639            ActivityRecord rootR = tr.getRootActivity();
3640            if (mController != null) {
3641                // Find the first activity that is not finishing.
3642                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3643                if (next != null) {
3644                    // ask watcher if this is allowed
3645                    boolean resumeOK = true;
3646                    try {
3647                        resumeOK = mController.activityResuming(next.packageName);
3648                    } catch (RemoteException e) {
3649                        mController = null;
3650                        Watchdog.getInstance().setActivityController(null);
3651                    }
3652
3653                    if (!resumeOK) {
3654                        return false;
3655                    }
3656                }
3657            }
3658            final long origId = Binder.clearCallingIdentity();
3659            try {
3660                boolean res;
3661                if (finishTask && r == rootR) {
3662                    // If requested, remove the task that is associated to this activity only if it
3663                    // was the root activity in the task.  The result code and data is ignored because
3664                    // we don't support returning them across task boundaries.
3665                    res = removeTaskByIdLocked(tr.taskId, 0);
3666                } else {
3667                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3668                            resultData, "app-request", true);
3669                }
3670                return res;
3671            } finally {
3672                Binder.restoreCallingIdentity(origId);
3673            }
3674        }
3675    }
3676
3677    @Override
3678    public final void finishHeavyWeightApp() {
3679        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3680                != PackageManager.PERMISSION_GRANTED) {
3681            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3682                    + Binder.getCallingPid()
3683                    + ", uid=" + Binder.getCallingUid()
3684                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3685            Slog.w(TAG, msg);
3686            throw new SecurityException(msg);
3687        }
3688
3689        synchronized(this) {
3690            if (mHeavyWeightProcess == null) {
3691                return;
3692            }
3693
3694            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3695                    mHeavyWeightProcess.activities);
3696            for (int i=0; i<activities.size(); i++) {
3697                ActivityRecord r = activities.get(i);
3698                if (!r.finishing) {
3699                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3700                            null, "finish-heavy", true);
3701                }
3702            }
3703
3704            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3705                    mHeavyWeightProcess.userId, 0));
3706            mHeavyWeightProcess = null;
3707        }
3708    }
3709
3710    @Override
3711    public void crashApplication(int uid, int initialPid, String packageName,
3712            String message) {
3713        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3714                != PackageManager.PERMISSION_GRANTED) {
3715            String msg = "Permission Denial: crashApplication() from pid="
3716                    + Binder.getCallingPid()
3717                    + ", uid=" + Binder.getCallingUid()
3718                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3719            Slog.w(TAG, msg);
3720            throw new SecurityException(msg);
3721        }
3722
3723        synchronized(this) {
3724            ProcessRecord proc = null;
3725
3726            // Figure out which process to kill.  We don't trust that initialPid
3727            // still has any relation to current pids, so must scan through the
3728            // list.
3729            synchronized (mPidsSelfLocked) {
3730                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3731                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3732                    if (p.uid != uid) {
3733                        continue;
3734                    }
3735                    if (p.pid == initialPid) {
3736                        proc = p;
3737                        break;
3738                    }
3739                    if (p.pkgList.containsKey(packageName)) {
3740                        proc = p;
3741                    }
3742                }
3743            }
3744
3745            if (proc == null) {
3746                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3747                        + " initialPid=" + initialPid
3748                        + " packageName=" + packageName);
3749                return;
3750            }
3751
3752            if (proc.thread != null) {
3753                if (proc.pid == Process.myPid()) {
3754                    Log.w(TAG, "crashApplication: trying to crash self!");
3755                    return;
3756                }
3757                long ident = Binder.clearCallingIdentity();
3758                try {
3759                    proc.thread.scheduleCrash(message);
3760                } catch (RemoteException e) {
3761                }
3762                Binder.restoreCallingIdentity(ident);
3763            }
3764        }
3765    }
3766
3767    @Override
3768    public final void finishSubActivity(IBinder token, String resultWho,
3769            int requestCode) {
3770        synchronized(this) {
3771            final long origId = Binder.clearCallingIdentity();
3772            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3773            if (r != null) {
3774                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3775            }
3776            Binder.restoreCallingIdentity(origId);
3777        }
3778    }
3779
3780    @Override
3781    public boolean finishActivityAffinity(IBinder token) {
3782        synchronized(this) {
3783            final long origId = Binder.clearCallingIdentity();
3784            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3785            boolean res = false;
3786            if (r != null) {
3787                res = r.task.stack.finishActivityAffinityLocked(r);
3788            }
3789            Binder.restoreCallingIdentity(origId);
3790            return res;
3791        }
3792    }
3793
3794    @Override
3795    public boolean willActivityBeVisible(IBinder token) {
3796        synchronized(this) {
3797            ActivityStack stack = ActivityRecord.getStackLocked(token);
3798            if (stack != null) {
3799                return stack.willActivityBeVisibleLocked(token);
3800            }
3801            return false;
3802        }
3803    }
3804
3805    @Override
3806    public void overridePendingTransition(IBinder token, String packageName,
3807            int enterAnim, int exitAnim) {
3808        synchronized(this) {
3809            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3810            if (self == null) {
3811                return;
3812            }
3813
3814            final long origId = Binder.clearCallingIdentity();
3815
3816            if (self.state == ActivityState.RESUMED
3817                    || self.state == ActivityState.PAUSING) {
3818                mWindowManager.overridePendingAppTransition(packageName,
3819                        enterAnim, exitAnim, null);
3820            }
3821
3822            Binder.restoreCallingIdentity(origId);
3823        }
3824    }
3825
3826    /**
3827     * Main function for removing an existing process from the activity manager
3828     * as a result of that process going away.  Clears out all connections
3829     * to the process.
3830     */
3831    private final void handleAppDiedLocked(ProcessRecord app,
3832            boolean restarting, boolean allowRestart) {
3833        int pid = app.pid;
3834        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3835        if (!restarting) {
3836            removeLruProcessLocked(app);
3837            if (pid > 0) {
3838                ProcessList.remove(pid);
3839            }
3840        }
3841
3842        if (mProfileProc == app) {
3843            clearProfilerLocked();
3844        }
3845
3846        // Remove this application's activities from active lists.
3847        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3848
3849        app.activities.clear();
3850
3851        if (app.instrumentationClass != null) {
3852            Slog.w(TAG, "Crash of app " + app.processName
3853                  + " running instrumentation " + app.instrumentationClass);
3854            Bundle info = new Bundle();
3855            info.putString("shortMsg", "Process crashed.");
3856            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3857        }
3858
3859        if (!restarting) {
3860            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3861                // If there was nothing to resume, and we are not already
3862                // restarting this process, but there is a visible activity that
3863                // is hosted by the process...  then make sure all visible
3864                // activities are running, taking care of restarting this
3865                // process.
3866                if (hasVisibleActivities) {
3867                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3868                }
3869            }
3870        }
3871    }
3872
3873    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3874        IBinder threadBinder = thread.asBinder();
3875        // Find the application record.
3876        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3877            ProcessRecord rec = mLruProcesses.get(i);
3878            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3879                return i;
3880            }
3881        }
3882        return -1;
3883    }
3884
3885    final ProcessRecord getRecordForAppLocked(
3886            IApplicationThread thread) {
3887        if (thread == null) {
3888            return null;
3889        }
3890
3891        int appIndex = getLRURecordIndexForAppLocked(thread);
3892        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3893    }
3894
3895    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3896        // If there are no longer any background processes running,
3897        // and the app that died was not running instrumentation,
3898        // then tell everyone we are now low on memory.
3899        boolean haveBg = false;
3900        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3901            ProcessRecord rec = mLruProcesses.get(i);
3902            if (rec.thread != null
3903                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3904                haveBg = true;
3905                break;
3906            }
3907        }
3908
3909        if (!haveBg) {
3910            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3911            if (doReport) {
3912                long now = SystemClock.uptimeMillis();
3913                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3914                    doReport = false;
3915                } else {
3916                    mLastMemUsageReportTime = now;
3917                }
3918            }
3919            final ArrayList<ProcessMemInfo> memInfos
3920                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3921            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3922            long now = SystemClock.uptimeMillis();
3923            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3924                ProcessRecord rec = mLruProcesses.get(i);
3925                if (rec == dyingProc || rec.thread == null) {
3926                    continue;
3927                }
3928                if (doReport) {
3929                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3930                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3931                }
3932                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3933                    // The low memory report is overriding any current
3934                    // state for a GC request.  Make sure to do
3935                    // heavy/important/visible/foreground processes first.
3936                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3937                        rec.lastRequestedGc = 0;
3938                    } else {
3939                        rec.lastRequestedGc = rec.lastLowMemory;
3940                    }
3941                    rec.reportLowMemory = true;
3942                    rec.lastLowMemory = now;
3943                    mProcessesToGc.remove(rec);
3944                    addProcessToGcListLocked(rec);
3945                }
3946            }
3947            if (doReport) {
3948                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3949                mHandler.sendMessage(msg);
3950            }
3951            scheduleAppGcsLocked();
3952        }
3953    }
3954
3955    final void appDiedLocked(ProcessRecord app, int pid,
3956            IApplicationThread thread) {
3957
3958        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3959        synchronized (stats) {
3960            stats.noteProcessDiedLocked(app.info.uid, pid);
3961        }
3962
3963        // Clean up already done if the process has been re-started.
3964        if (app.pid == pid && app.thread != null &&
3965                app.thread.asBinder() == thread.asBinder()) {
3966            boolean doLowMem = app.instrumentationClass == null;
3967            boolean doOomAdj = doLowMem;
3968            if (!app.killedByAm) {
3969                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3970                        + ") has died.");
3971                mAllowLowerMemLevel = true;
3972            } else {
3973                // Note that we always want to do oom adj to update our state with the
3974                // new number of procs.
3975                mAllowLowerMemLevel = false;
3976                doLowMem = false;
3977            }
3978            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3979            if (DEBUG_CLEANUP) Slog.v(
3980                TAG, "Dying app: " + app + ", pid: " + pid
3981                + ", thread: " + thread.asBinder());
3982            handleAppDiedLocked(app, false, true);
3983
3984            if (doOomAdj) {
3985                updateOomAdjLocked();
3986            }
3987            if (doLowMem) {
3988                doLowMemReportIfNeededLocked(app);
3989            }
3990        } else if (app.pid != pid) {
3991            // A new process has already been started.
3992            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3993                    + ") has died and restarted (pid " + app.pid + ").");
3994            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3995        } else if (DEBUG_PROCESSES) {
3996            Slog.d(TAG, "Received spurious death notification for thread "
3997                    + thread.asBinder());
3998        }
3999    }
4000
4001    /**
4002     * If a stack trace dump file is configured, dump process stack traces.
4003     * @param clearTraces causes the dump file to be erased prior to the new
4004     *    traces being written, if true; when false, the new traces will be
4005     *    appended to any existing file content.
4006     * @param firstPids of dalvik VM processes to dump stack traces for first
4007     * @param lastPids of dalvik VM processes to dump stack traces for last
4008     * @param nativeProcs optional list of native process names to dump stack crawls
4009     * @return file containing stack traces, or null if no dump file is configured
4010     */
4011    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4012            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4013        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4014        if (tracesPath == null || tracesPath.length() == 0) {
4015            return null;
4016        }
4017
4018        File tracesFile = new File(tracesPath);
4019        try {
4020            File tracesDir = tracesFile.getParentFile();
4021            if (!tracesDir.exists()) {
4022                tracesFile.mkdirs();
4023                if (!SELinux.restorecon(tracesDir)) {
4024                    return null;
4025                }
4026            }
4027            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4028
4029            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4030            tracesFile.createNewFile();
4031            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4032        } catch (IOException e) {
4033            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4034            return null;
4035        }
4036
4037        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4038        return tracesFile;
4039    }
4040
4041    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4042            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4043        // Use a FileObserver to detect when traces finish writing.
4044        // The order of traces is considered important to maintain for legibility.
4045        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4046            @Override
4047            public synchronized void onEvent(int event, String path) { notify(); }
4048        };
4049
4050        try {
4051            observer.startWatching();
4052
4053            // First collect all of the stacks of the most important pids.
4054            if (firstPids != null) {
4055                try {
4056                    int num = firstPids.size();
4057                    for (int i = 0; i < num; i++) {
4058                        synchronized (observer) {
4059                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4060                            observer.wait(200);  // Wait for write-close, give up after 200msec
4061                        }
4062                    }
4063                } catch (InterruptedException e) {
4064                    Log.wtf(TAG, e);
4065                }
4066            }
4067
4068            // Next collect the stacks of the native pids
4069            if (nativeProcs != null) {
4070                int[] pids = Process.getPidsForCommands(nativeProcs);
4071                if (pids != null) {
4072                    for (int pid : pids) {
4073                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4074                    }
4075                }
4076            }
4077
4078            // Lastly, measure CPU usage.
4079            if (processCpuTracker != null) {
4080                processCpuTracker.init();
4081                System.gc();
4082                processCpuTracker.update();
4083                try {
4084                    synchronized (processCpuTracker) {
4085                        processCpuTracker.wait(500); // measure over 1/2 second.
4086                    }
4087                } catch (InterruptedException e) {
4088                }
4089                processCpuTracker.update();
4090
4091                // We'll take the stack crawls of just the top apps using CPU.
4092                final int N = processCpuTracker.countWorkingStats();
4093                int numProcs = 0;
4094                for (int i=0; i<N && numProcs<5; i++) {
4095                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4096                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4097                        numProcs++;
4098                        try {
4099                            synchronized (observer) {
4100                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4101                                observer.wait(200);  // Wait for write-close, give up after 200msec
4102                            }
4103                        } catch (InterruptedException e) {
4104                            Log.wtf(TAG, e);
4105                        }
4106
4107                    }
4108                }
4109            }
4110        } finally {
4111            observer.stopWatching();
4112        }
4113    }
4114
4115    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4116        if (true || IS_USER_BUILD) {
4117            return;
4118        }
4119        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4120        if (tracesPath == null || tracesPath.length() == 0) {
4121            return;
4122        }
4123
4124        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4125        StrictMode.allowThreadDiskWrites();
4126        try {
4127            final File tracesFile = new File(tracesPath);
4128            final File tracesDir = tracesFile.getParentFile();
4129            final File tracesTmp = new File(tracesDir, "__tmp__");
4130            try {
4131                if (!tracesDir.exists()) {
4132                    tracesFile.mkdirs();
4133                    if (!SELinux.restorecon(tracesDir.getPath())) {
4134                        return;
4135                    }
4136                }
4137                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4138
4139                if (tracesFile.exists()) {
4140                    tracesTmp.delete();
4141                    tracesFile.renameTo(tracesTmp);
4142                }
4143                StringBuilder sb = new StringBuilder();
4144                Time tobj = new Time();
4145                tobj.set(System.currentTimeMillis());
4146                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4147                sb.append(": ");
4148                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4149                sb.append(" since ");
4150                sb.append(msg);
4151                FileOutputStream fos = new FileOutputStream(tracesFile);
4152                fos.write(sb.toString().getBytes());
4153                if (app == null) {
4154                    fos.write("\n*** No application process!".getBytes());
4155                }
4156                fos.close();
4157                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4158            } catch (IOException e) {
4159                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4160                return;
4161            }
4162
4163            if (app != null) {
4164                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4165                firstPids.add(app.pid);
4166                dumpStackTraces(tracesPath, firstPids, null, null, null);
4167            }
4168
4169            File lastTracesFile = null;
4170            File curTracesFile = null;
4171            for (int i=9; i>=0; i--) {
4172                String name = String.format(Locale.US, "slow%02d.txt", i);
4173                curTracesFile = new File(tracesDir, name);
4174                if (curTracesFile.exists()) {
4175                    if (lastTracesFile != null) {
4176                        curTracesFile.renameTo(lastTracesFile);
4177                    } else {
4178                        curTracesFile.delete();
4179                    }
4180                }
4181                lastTracesFile = curTracesFile;
4182            }
4183            tracesFile.renameTo(curTracesFile);
4184            if (tracesTmp.exists()) {
4185                tracesTmp.renameTo(tracesFile);
4186            }
4187        } finally {
4188            StrictMode.setThreadPolicy(oldPolicy);
4189        }
4190    }
4191
4192    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4193            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4194        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4195        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4196
4197        if (mController != null) {
4198            try {
4199                // 0 == continue, -1 = kill process immediately
4200                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4201                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4202            } catch (RemoteException e) {
4203                mController = null;
4204                Watchdog.getInstance().setActivityController(null);
4205            }
4206        }
4207
4208        long anrTime = SystemClock.uptimeMillis();
4209        if (MONITOR_CPU_USAGE) {
4210            updateCpuStatsNow();
4211        }
4212
4213        synchronized (this) {
4214            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4215            if (mShuttingDown) {
4216                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4217                return;
4218            } else if (app.notResponding) {
4219                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4220                return;
4221            } else if (app.crashing) {
4222                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4223                return;
4224            }
4225
4226            // In case we come through here for the same app before completing
4227            // this one, mark as anring now so we will bail out.
4228            app.notResponding = true;
4229
4230            // Log the ANR to the event log.
4231            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4232                    app.processName, app.info.flags, annotation);
4233
4234            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4235            firstPids.add(app.pid);
4236
4237            int parentPid = app.pid;
4238            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4239            if (parentPid != app.pid) firstPids.add(parentPid);
4240
4241            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4242
4243            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4244                ProcessRecord r = mLruProcesses.get(i);
4245                if (r != null && r.thread != null) {
4246                    int pid = r.pid;
4247                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4248                        if (r.persistent) {
4249                            firstPids.add(pid);
4250                        } else {
4251                            lastPids.put(pid, Boolean.TRUE);
4252                        }
4253                    }
4254                }
4255            }
4256        }
4257
4258        // Log the ANR to the main log.
4259        StringBuilder info = new StringBuilder();
4260        info.setLength(0);
4261        info.append("ANR in ").append(app.processName);
4262        if (activity != null && activity.shortComponentName != null) {
4263            info.append(" (").append(activity.shortComponentName).append(")");
4264        }
4265        info.append("\n");
4266        info.append("PID: ").append(app.pid).append("\n");
4267        if (annotation != null) {
4268            info.append("Reason: ").append(annotation).append("\n");
4269        }
4270        if (parent != null && parent != activity) {
4271            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4272        }
4273
4274        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4275
4276        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4277                NATIVE_STACKS_OF_INTEREST);
4278
4279        String cpuInfo = null;
4280        if (MONITOR_CPU_USAGE) {
4281            updateCpuStatsNow();
4282            synchronized (mProcessCpuThread) {
4283                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4284            }
4285            info.append(processCpuTracker.printCurrentLoad());
4286            info.append(cpuInfo);
4287        }
4288
4289        info.append(processCpuTracker.printCurrentState(anrTime));
4290
4291        Slog.e(TAG, info.toString());
4292        if (tracesFile == null) {
4293            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4294            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4295        }
4296
4297        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4298                cpuInfo, tracesFile, null);
4299
4300        if (mController != null) {
4301            try {
4302                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4303                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4304                if (res != 0) {
4305                    if (res < 0 && app.pid != MY_PID) {
4306                        Process.killProcess(app.pid);
4307                    } else {
4308                        synchronized (this) {
4309                            mServices.scheduleServiceTimeoutLocked(app);
4310                        }
4311                    }
4312                    return;
4313                }
4314            } catch (RemoteException e) {
4315                mController = null;
4316                Watchdog.getInstance().setActivityController(null);
4317            }
4318        }
4319
4320        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4321        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4322                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4323
4324        synchronized (this) {
4325            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4326                killUnneededProcessLocked(app, "background ANR");
4327                return;
4328            }
4329
4330            // Set the app's notResponding state, and look up the errorReportReceiver
4331            makeAppNotRespondingLocked(app,
4332                    activity != null ? activity.shortComponentName : null,
4333                    annotation != null ? "ANR " + annotation : "ANR",
4334                    info.toString());
4335
4336            // Bring up the infamous App Not Responding dialog
4337            Message msg = Message.obtain();
4338            HashMap<String, Object> map = new HashMap<String, Object>();
4339            msg.what = SHOW_NOT_RESPONDING_MSG;
4340            msg.obj = map;
4341            msg.arg1 = aboveSystem ? 1 : 0;
4342            map.put("app", app);
4343            if (activity != null) {
4344                map.put("activity", activity);
4345            }
4346
4347            mHandler.sendMessage(msg);
4348        }
4349    }
4350
4351    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4352        if (!mLaunchWarningShown) {
4353            mLaunchWarningShown = true;
4354            mHandler.post(new Runnable() {
4355                @Override
4356                public void run() {
4357                    synchronized (ActivityManagerService.this) {
4358                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4359                        d.show();
4360                        mHandler.postDelayed(new Runnable() {
4361                            @Override
4362                            public void run() {
4363                                synchronized (ActivityManagerService.this) {
4364                                    d.dismiss();
4365                                    mLaunchWarningShown = false;
4366                                }
4367                            }
4368                        }, 4000);
4369                    }
4370                }
4371            });
4372        }
4373    }
4374
4375    @Override
4376    public boolean clearApplicationUserData(final String packageName,
4377            final IPackageDataObserver observer, int userId) {
4378        enforceNotIsolatedCaller("clearApplicationUserData");
4379        int uid = Binder.getCallingUid();
4380        int pid = Binder.getCallingPid();
4381        userId = handleIncomingUser(pid, uid,
4382                userId, false, true, "clearApplicationUserData", null);
4383        long callingId = Binder.clearCallingIdentity();
4384        try {
4385            IPackageManager pm = AppGlobals.getPackageManager();
4386            int pkgUid = -1;
4387            synchronized(this) {
4388                try {
4389                    pkgUid = pm.getPackageUid(packageName, userId);
4390                } catch (RemoteException e) {
4391                }
4392                if (pkgUid == -1) {
4393                    Slog.w(TAG, "Invalid packageName: " + packageName);
4394                    if (observer != null) {
4395                        try {
4396                            observer.onRemoveCompleted(packageName, false);
4397                        } catch (RemoteException e) {
4398                            Slog.i(TAG, "Observer no longer exists.");
4399                        }
4400                    }
4401                    return false;
4402                }
4403                if (uid == pkgUid || checkComponentPermission(
4404                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4405                        pid, uid, -1, true)
4406                        == PackageManager.PERMISSION_GRANTED) {
4407                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4408                } else {
4409                    throw new SecurityException("PID " + pid + " does not have permission "
4410                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4411                                    + " of package " + packageName);
4412                }
4413            }
4414
4415            try {
4416                // Clear application user data
4417                pm.clearApplicationUserData(packageName, observer, userId);
4418
4419                // Remove all permissions granted from/to this package
4420                removeUriPermissionsForPackageLocked(packageName, userId, true);
4421
4422                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4423                        Uri.fromParts("package", packageName, null));
4424                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4425                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4426                        null, null, 0, null, null, null, false, false, userId);
4427            } catch (RemoteException e) {
4428            }
4429        } finally {
4430            Binder.restoreCallingIdentity(callingId);
4431        }
4432        return true;
4433    }
4434
4435    @Override
4436    public void killBackgroundProcesses(final String packageName, int userId) {
4437        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4438                != PackageManager.PERMISSION_GRANTED &&
4439                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4440                        != PackageManager.PERMISSION_GRANTED) {
4441            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4442                    + Binder.getCallingPid()
4443                    + ", uid=" + Binder.getCallingUid()
4444                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4445            Slog.w(TAG, msg);
4446            throw new SecurityException(msg);
4447        }
4448
4449        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4450                userId, true, true, "killBackgroundProcesses", null);
4451        long callingId = Binder.clearCallingIdentity();
4452        try {
4453            IPackageManager pm = AppGlobals.getPackageManager();
4454            synchronized(this) {
4455                int appId = -1;
4456                try {
4457                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4458                } catch (RemoteException e) {
4459                }
4460                if (appId == -1) {
4461                    Slog.w(TAG, "Invalid packageName: " + packageName);
4462                    return;
4463                }
4464                killPackageProcessesLocked(packageName, appId, userId,
4465                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4466            }
4467        } finally {
4468            Binder.restoreCallingIdentity(callingId);
4469        }
4470    }
4471
4472    @Override
4473    public void killAllBackgroundProcesses() {
4474        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4475                != PackageManager.PERMISSION_GRANTED) {
4476            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4477                    + Binder.getCallingPid()
4478                    + ", uid=" + Binder.getCallingUid()
4479                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4480            Slog.w(TAG, msg);
4481            throw new SecurityException(msg);
4482        }
4483
4484        long callingId = Binder.clearCallingIdentity();
4485        try {
4486            synchronized(this) {
4487                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4488                final int NP = mProcessNames.getMap().size();
4489                for (int ip=0; ip<NP; ip++) {
4490                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4491                    final int NA = apps.size();
4492                    for (int ia=0; ia<NA; ia++) {
4493                        ProcessRecord app = apps.valueAt(ia);
4494                        if (app.persistent) {
4495                            // we don't kill persistent processes
4496                            continue;
4497                        }
4498                        if (app.removed) {
4499                            procs.add(app);
4500                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4501                            app.removed = true;
4502                            procs.add(app);
4503                        }
4504                    }
4505                }
4506
4507                int N = procs.size();
4508                for (int i=0; i<N; i++) {
4509                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4510                }
4511                mAllowLowerMemLevel = true;
4512                updateOomAdjLocked();
4513                doLowMemReportIfNeededLocked(null);
4514            }
4515        } finally {
4516            Binder.restoreCallingIdentity(callingId);
4517        }
4518    }
4519
4520    @Override
4521    public void forceStopPackage(final String packageName, int userId) {
4522        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4523                != PackageManager.PERMISSION_GRANTED) {
4524            String msg = "Permission Denial: forceStopPackage() from pid="
4525                    + Binder.getCallingPid()
4526                    + ", uid=" + Binder.getCallingUid()
4527                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4528            Slog.w(TAG, msg);
4529            throw new SecurityException(msg);
4530        }
4531        final int callingPid = Binder.getCallingPid();
4532        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4533                userId, true, true, "forceStopPackage", null);
4534        long callingId = Binder.clearCallingIdentity();
4535        try {
4536            IPackageManager pm = AppGlobals.getPackageManager();
4537            synchronized(this) {
4538                int[] users = userId == UserHandle.USER_ALL
4539                        ? getUsersLocked() : new int[] { userId };
4540                for (int user : users) {
4541                    int pkgUid = -1;
4542                    try {
4543                        pkgUid = pm.getPackageUid(packageName, user);
4544                    } catch (RemoteException e) {
4545                    }
4546                    if (pkgUid == -1) {
4547                        Slog.w(TAG, "Invalid packageName: " + packageName);
4548                        continue;
4549                    }
4550                    try {
4551                        pm.setPackageStoppedState(packageName, true, user);
4552                    } catch (RemoteException e) {
4553                    } catch (IllegalArgumentException e) {
4554                        Slog.w(TAG, "Failed trying to unstop package "
4555                                + packageName + ": " + e);
4556                    }
4557                    if (isUserRunningLocked(user, false)) {
4558                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4559                    }
4560                }
4561            }
4562        } finally {
4563            Binder.restoreCallingIdentity(callingId);
4564        }
4565    }
4566
4567    /*
4568     * The pkg name and app id have to be specified.
4569     */
4570    @Override
4571    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4572        if (pkg == null) {
4573            return;
4574        }
4575        // Make sure the uid is valid.
4576        if (appid < 0) {
4577            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4578            return;
4579        }
4580        int callerUid = Binder.getCallingUid();
4581        // Only the system server can kill an application
4582        if (callerUid == Process.SYSTEM_UID) {
4583            // Post an aysnc message to kill the application
4584            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4585            msg.arg1 = appid;
4586            msg.arg2 = 0;
4587            Bundle bundle = new Bundle();
4588            bundle.putString("pkg", pkg);
4589            bundle.putString("reason", reason);
4590            msg.obj = bundle;
4591            mHandler.sendMessage(msg);
4592        } else {
4593            throw new SecurityException(callerUid + " cannot kill pkg: " +
4594                    pkg);
4595        }
4596    }
4597
4598    @Override
4599    public void closeSystemDialogs(String reason) {
4600        enforceNotIsolatedCaller("closeSystemDialogs");
4601
4602        final int pid = Binder.getCallingPid();
4603        final int uid = Binder.getCallingUid();
4604        final long origId = Binder.clearCallingIdentity();
4605        try {
4606            synchronized (this) {
4607                // Only allow this from foreground processes, so that background
4608                // applications can't abuse it to prevent system UI from being shown.
4609                if (uid >= Process.FIRST_APPLICATION_UID) {
4610                    ProcessRecord proc;
4611                    synchronized (mPidsSelfLocked) {
4612                        proc = mPidsSelfLocked.get(pid);
4613                    }
4614                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4615                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4616                                + " from background process " + proc);
4617                        return;
4618                    }
4619                }
4620                closeSystemDialogsLocked(reason);
4621            }
4622        } finally {
4623            Binder.restoreCallingIdentity(origId);
4624        }
4625    }
4626
4627    void closeSystemDialogsLocked(String reason) {
4628        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4629        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4630                | Intent.FLAG_RECEIVER_FOREGROUND);
4631        if (reason != null) {
4632            intent.putExtra("reason", reason);
4633        }
4634        mWindowManager.closeSystemDialogs(reason);
4635
4636        mStackSupervisor.closeSystemDialogsLocked();
4637
4638        broadcastIntentLocked(null, null, intent, null,
4639                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4640                Process.SYSTEM_UID, UserHandle.USER_ALL);
4641    }
4642
4643    @Override
4644    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4645        enforceNotIsolatedCaller("getProcessMemoryInfo");
4646        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4647        for (int i=pids.length-1; i>=0; i--) {
4648            ProcessRecord proc;
4649            int oomAdj;
4650            synchronized (this) {
4651                synchronized (mPidsSelfLocked) {
4652                    proc = mPidsSelfLocked.get(pids[i]);
4653                    oomAdj = proc != null ? proc.setAdj : 0;
4654                }
4655            }
4656            infos[i] = new Debug.MemoryInfo();
4657            Debug.getMemoryInfo(pids[i], infos[i]);
4658            if (proc != null) {
4659                synchronized (this) {
4660                    if (proc.thread != null && proc.setAdj == oomAdj) {
4661                        // Record this for posterity if the process has been stable.
4662                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4663                                infos[i].getTotalUss(), false, proc.pkgList);
4664                    }
4665                }
4666            }
4667        }
4668        return infos;
4669    }
4670
4671    @Override
4672    public long[] getProcessPss(int[] pids) {
4673        enforceNotIsolatedCaller("getProcessPss");
4674        long[] pss = new long[pids.length];
4675        for (int i=pids.length-1; i>=0; i--) {
4676            ProcessRecord proc;
4677            int oomAdj;
4678            synchronized (this) {
4679                synchronized (mPidsSelfLocked) {
4680                    proc = mPidsSelfLocked.get(pids[i]);
4681                    oomAdj = proc != null ? proc.setAdj : 0;
4682                }
4683            }
4684            long[] tmpUss = new long[1];
4685            pss[i] = Debug.getPss(pids[i], tmpUss);
4686            if (proc != null) {
4687                synchronized (this) {
4688                    if (proc.thread != null && proc.setAdj == oomAdj) {
4689                        // Record this for posterity if the process has been stable.
4690                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4691                    }
4692                }
4693            }
4694        }
4695        return pss;
4696    }
4697
4698    @Override
4699    public void killApplicationProcess(String processName, int uid) {
4700        if (processName == null) {
4701            return;
4702        }
4703
4704        int callerUid = Binder.getCallingUid();
4705        // Only the system server can kill an application
4706        if (callerUid == Process.SYSTEM_UID) {
4707            synchronized (this) {
4708                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4709                if (app != null && app.thread != null) {
4710                    try {
4711                        app.thread.scheduleSuicide();
4712                    } catch (RemoteException e) {
4713                        // If the other end already died, then our work here is done.
4714                    }
4715                } else {
4716                    Slog.w(TAG, "Process/uid not found attempting kill of "
4717                            + processName + " / " + uid);
4718                }
4719            }
4720        } else {
4721            throw new SecurityException(callerUid + " cannot kill app process: " +
4722                    processName);
4723        }
4724    }
4725
4726    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4727        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4728                false, true, false, false, UserHandle.getUserId(uid), reason);
4729        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4730                Uri.fromParts("package", packageName, null));
4731        if (!mProcessesReady) {
4732            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4733                    | Intent.FLAG_RECEIVER_FOREGROUND);
4734        }
4735        intent.putExtra(Intent.EXTRA_UID, uid);
4736        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4737        broadcastIntentLocked(null, null, intent,
4738                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4739                false, false,
4740                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4741    }
4742
4743    private void forceStopUserLocked(int userId, String reason) {
4744        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4745        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4746        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4747                | Intent.FLAG_RECEIVER_FOREGROUND);
4748        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4749        broadcastIntentLocked(null, null, intent,
4750                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4751                false, false,
4752                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4753    }
4754
4755    private final boolean killPackageProcessesLocked(String packageName, int appId,
4756            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4757            boolean doit, boolean evenPersistent, String reason) {
4758        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4759
4760        // Remove all processes this package may have touched: all with the
4761        // same UID (except for the system or root user), and all whose name
4762        // matches the package name.
4763        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4764        final int NP = mProcessNames.getMap().size();
4765        for (int ip=0; ip<NP; ip++) {
4766            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4767            final int NA = apps.size();
4768            for (int ia=0; ia<NA; ia++) {
4769                ProcessRecord app = apps.valueAt(ia);
4770                if (app.persistent && !evenPersistent) {
4771                    // we don't kill persistent processes
4772                    continue;
4773                }
4774                if (app.removed) {
4775                    if (doit) {
4776                        procs.add(app);
4777                    }
4778                    continue;
4779                }
4780
4781                // Skip process if it doesn't meet our oom adj requirement.
4782                if (app.setAdj < minOomAdj) {
4783                    continue;
4784                }
4785
4786                // If no package is specified, we call all processes under the
4787                // give user id.
4788                if (packageName == null) {
4789                    if (app.userId != userId) {
4790                        continue;
4791                    }
4792                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4793                        continue;
4794                    }
4795                // Package has been specified, we want to hit all processes
4796                // that match it.  We need to qualify this by the processes
4797                // that are running under the specified app and user ID.
4798                } else {
4799                    if (UserHandle.getAppId(app.uid) != appId) {
4800                        continue;
4801                    }
4802                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4803                        continue;
4804                    }
4805                    if (!app.pkgList.containsKey(packageName)) {
4806                        continue;
4807                    }
4808                }
4809
4810                // Process has passed all conditions, kill it!
4811                if (!doit) {
4812                    return true;
4813                }
4814                app.removed = true;
4815                procs.add(app);
4816            }
4817        }
4818
4819        int N = procs.size();
4820        for (int i=0; i<N; i++) {
4821            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4822        }
4823        updateOomAdjLocked();
4824        return N > 0;
4825    }
4826
4827    private final boolean forceStopPackageLocked(String name, int appId,
4828            boolean callerWillRestart, boolean purgeCache, boolean doit,
4829            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4830        int i;
4831        int N;
4832
4833        if (userId == UserHandle.USER_ALL && name == null) {
4834            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4835        }
4836
4837        if (appId < 0 && name != null) {
4838            try {
4839                appId = UserHandle.getAppId(
4840                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4841            } catch (RemoteException e) {
4842            }
4843        }
4844
4845        if (doit) {
4846            if (name != null) {
4847                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4848                        + " user=" + userId + ": " + reason);
4849            } else {
4850                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4851            }
4852
4853            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4854            for (int ip=pmap.size()-1; ip>=0; ip--) {
4855                SparseArray<Long> ba = pmap.valueAt(ip);
4856                for (i=ba.size()-1; i>=0; i--) {
4857                    boolean remove = false;
4858                    final int entUid = ba.keyAt(i);
4859                    if (name != null) {
4860                        if (userId == UserHandle.USER_ALL) {
4861                            if (UserHandle.getAppId(entUid) == appId) {
4862                                remove = true;
4863                            }
4864                        } else {
4865                            if (entUid == UserHandle.getUid(userId, appId)) {
4866                                remove = true;
4867                            }
4868                        }
4869                    } else if (UserHandle.getUserId(entUid) == userId) {
4870                        remove = true;
4871                    }
4872                    if (remove) {
4873                        ba.removeAt(i);
4874                    }
4875                }
4876                if (ba.size() == 0) {
4877                    pmap.removeAt(ip);
4878                }
4879            }
4880        }
4881
4882        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4883                -100, callerWillRestart, true, doit, evenPersistent,
4884                name == null ? ("stop user " + userId) : ("stop " + name));
4885
4886        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4887            if (!doit) {
4888                return true;
4889            }
4890            didSomething = true;
4891        }
4892
4893        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4894            if (!doit) {
4895                return true;
4896            }
4897            didSomething = true;
4898        }
4899
4900        if (name == null) {
4901            // Remove all sticky broadcasts from this user.
4902            mStickyBroadcasts.remove(userId);
4903        }
4904
4905        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4906        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4907                userId, providers)) {
4908            if (!doit) {
4909                return true;
4910            }
4911            didSomething = true;
4912        }
4913        N = providers.size();
4914        for (i=0; i<N; i++) {
4915            removeDyingProviderLocked(null, providers.get(i), true);
4916        }
4917
4918        // Remove transient permissions granted from/to this package/user
4919        removeUriPermissionsForPackageLocked(name, userId, false);
4920
4921        if (name == null || uninstalling) {
4922            // Remove pending intents.  For now we only do this when force
4923            // stopping users, because we have some problems when doing this
4924            // for packages -- app widgets are not currently cleaned up for
4925            // such packages, so they can be left with bad pending intents.
4926            if (mIntentSenderRecords.size() > 0) {
4927                Iterator<WeakReference<PendingIntentRecord>> it
4928                        = mIntentSenderRecords.values().iterator();
4929                while (it.hasNext()) {
4930                    WeakReference<PendingIntentRecord> wpir = it.next();
4931                    if (wpir == null) {
4932                        it.remove();
4933                        continue;
4934                    }
4935                    PendingIntentRecord pir = wpir.get();
4936                    if (pir == null) {
4937                        it.remove();
4938                        continue;
4939                    }
4940                    if (name == null) {
4941                        // Stopping user, remove all objects for the user.
4942                        if (pir.key.userId != userId) {
4943                            // Not the same user, skip it.
4944                            continue;
4945                        }
4946                    } else {
4947                        if (UserHandle.getAppId(pir.uid) != appId) {
4948                            // Different app id, skip it.
4949                            continue;
4950                        }
4951                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4952                            // Different user, skip it.
4953                            continue;
4954                        }
4955                        if (!pir.key.packageName.equals(name)) {
4956                            // Different package, skip it.
4957                            continue;
4958                        }
4959                    }
4960                    if (!doit) {
4961                        return true;
4962                    }
4963                    didSomething = true;
4964                    it.remove();
4965                    pir.canceled = true;
4966                    if (pir.key.activity != null) {
4967                        pir.key.activity.pendingResults.remove(pir.ref);
4968                    }
4969                }
4970            }
4971        }
4972
4973        if (doit) {
4974            if (purgeCache && name != null) {
4975                AttributeCache ac = AttributeCache.instance();
4976                if (ac != null) {
4977                    ac.removePackage(name);
4978                }
4979            }
4980            if (mBooted) {
4981                mStackSupervisor.resumeTopActivitiesLocked();
4982                mStackSupervisor.scheduleIdleLocked();
4983            }
4984        }
4985
4986        return didSomething;
4987    }
4988
4989    private final boolean removeProcessLocked(ProcessRecord app,
4990            boolean callerWillRestart, boolean allowRestart, String reason) {
4991        final String name = app.processName;
4992        final int uid = app.uid;
4993        if (DEBUG_PROCESSES) Slog.d(
4994            TAG, "Force removing proc " + app.toShortString() + " (" + name
4995            + "/" + uid + ")");
4996
4997        mProcessNames.remove(name, uid);
4998        mIsolatedProcesses.remove(app.uid);
4999        if (mHeavyWeightProcess == app) {
5000            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5001                    mHeavyWeightProcess.userId, 0));
5002            mHeavyWeightProcess = null;
5003        }
5004        boolean needRestart = false;
5005        if (app.pid > 0 && app.pid != MY_PID) {
5006            int pid = app.pid;
5007            synchronized (mPidsSelfLocked) {
5008                mPidsSelfLocked.remove(pid);
5009                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5010            }
5011            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5012                    app.processName, app.info.uid);
5013            if (app.isolated) {
5014                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5015            }
5016            killUnneededProcessLocked(app, reason);
5017            handleAppDiedLocked(app, true, allowRestart);
5018            removeLruProcessLocked(app);
5019
5020            if (app.persistent && !app.isolated) {
5021                if (!callerWillRestart) {
5022                    addAppLocked(app.info, false);
5023                } else {
5024                    needRestart = true;
5025                }
5026            }
5027        } else {
5028            mRemovedProcesses.add(app);
5029        }
5030
5031        return needRestart;
5032    }
5033
5034    private final void processStartTimedOutLocked(ProcessRecord app) {
5035        final int pid = app.pid;
5036        boolean gone = false;
5037        synchronized (mPidsSelfLocked) {
5038            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5039            if (knownApp != null && knownApp.thread == null) {
5040                mPidsSelfLocked.remove(pid);
5041                gone = true;
5042            }
5043        }
5044
5045        if (gone) {
5046            Slog.w(TAG, "Process " + app + " failed to attach");
5047            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5048                    pid, app.uid, app.processName);
5049            mProcessNames.remove(app.processName, app.uid);
5050            mIsolatedProcesses.remove(app.uid);
5051            if (mHeavyWeightProcess == app) {
5052                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5053                        mHeavyWeightProcess.userId, 0));
5054                mHeavyWeightProcess = null;
5055            }
5056            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5057                    app.processName, app.info.uid);
5058            if (app.isolated) {
5059                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5060            }
5061            // Take care of any launching providers waiting for this process.
5062            checkAppInLaunchingProvidersLocked(app, true);
5063            // Take care of any services that are waiting for the process.
5064            mServices.processStartTimedOutLocked(app);
5065            killUnneededProcessLocked(app, "start timeout");
5066            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5067                Slog.w(TAG, "Unattached app died before backup, skipping");
5068                try {
5069                    IBackupManager bm = IBackupManager.Stub.asInterface(
5070                            ServiceManager.getService(Context.BACKUP_SERVICE));
5071                    bm.agentDisconnected(app.info.packageName);
5072                } catch (RemoteException e) {
5073                    // Can't happen; the backup manager is local
5074                }
5075            }
5076            if (isPendingBroadcastProcessLocked(pid)) {
5077                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5078                skipPendingBroadcastLocked(pid);
5079            }
5080        } else {
5081            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5082        }
5083    }
5084
5085    private final boolean attachApplicationLocked(IApplicationThread thread,
5086            int pid) {
5087
5088        // Find the application record that is being attached...  either via
5089        // the pid if we are running in multiple processes, or just pull the
5090        // next app record if we are emulating process with anonymous threads.
5091        ProcessRecord app;
5092        if (pid != MY_PID && pid >= 0) {
5093            synchronized (mPidsSelfLocked) {
5094                app = mPidsSelfLocked.get(pid);
5095            }
5096        } else {
5097            app = null;
5098        }
5099
5100        if (app == null) {
5101            Slog.w(TAG, "No pending application record for pid " + pid
5102                    + " (IApplicationThread " + thread + "); dropping process");
5103            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5104            if (pid > 0 && pid != MY_PID) {
5105                Process.killProcessQuiet(pid);
5106            } else {
5107                try {
5108                    thread.scheduleExit();
5109                } catch (Exception e) {
5110                    // Ignore exceptions.
5111                }
5112            }
5113            return false;
5114        }
5115
5116        // If this application record is still attached to a previous
5117        // process, clean it up now.
5118        if (app.thread != null) {
5119            handleAppDiedLocked(app, true, true);
5120        }
5121
5122        // Tell the process all about itself.
5123
5124        if (localLOGV) Slog.v(
5125                TAG, "Binding process pid " + pid + " to record " + app);
5126
5127        final String processName = app.processName;
5128        try {
5129            AppDeathRecipient adr = new AppDeathRecipient(
5130                    app, pid, thread);
5131            thread.asBinder().linkToDeath(adr, 0);
5132            app.deathRecipient = adr;
5133        } catch (RemoteException e) {
5134            app.resetPackageList(mProcessStats);
5135            startProcessLocked(app, "link fail", processName);
5136            return false;
5137        }
5138
5139        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5140
5141        app.makeActive(thread, mProcessStats);
5142        app.curAdj = app.setAdj = -100;
5143        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5144        app.forcingToForeground = null;
5145        updateProcessForegroundLocked(app, false, false);
5146        app.hasShownUi = false;
5147        app.debugging = false;
5148        app.cached = false;
5149
5150        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5151
5152        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5153        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5154
5155        if (!normalMode) {
5156            Slog.i(TAG, "Launching preboot mode app: " + app);
5157        }
5158
5159        if (localLOGV) Slog.v(
5160            TAG, "New app record " + app
5161            + " thread=" + thread.asBinder() + " pid=" + pid);
5162        try {
5163            int testMode = IApplicationThread.DEBUG_OFF;
5164            if (mDebugApp != null && mDebugApp.equals(processName)) {
5165                testMode = mWaitForDebugger
5166                    ? IApplicationThread.DEBUG_WAIT
5167                    : IApplicationThread.DEBUG_ON;
5168                app.debugging = true;
5169                if (mDebugTransient) {
5170                    mDebugApp = mOrigDebugApp;
5171                    mWaitForDebugger = mOrigWaitForDebugger;
5172                }
5173            }
5174            String profileFile = app.instrumentationProfileFile;
5175            ParcelFileDescriptor profileFd = null;
5176            boolean profileAutoStop = false;
5177            if (mProfileApp != null && mProfileApp.equals(processName)) {
5178                mProfileProc = app;
5179                profileFile = mProfileFile;
5180                profileFd = mProfileFd;
5181                profileAutoStop = mAutoStopProfiler;
5182            }
5183            boolean enableOpenGlTrace = false;
5184            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5185                enableOpenGlTrace = true;
5186                mOpenGlTraceApp = null;
5187            }
5188
5189            // If the app is being launched for restore or full backup, set it up specially
5190            boolean isRestrictedBackupMode = false;
5191            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5192                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5193                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5194                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5195            }
5196
5197            ensurePackageDexOpt(app.instrumentationInfo != null
5198                    ? app.instrumentationInfo.packageName
5199                    : app.info.packageName);
5200            if (app.instrumentationClass != null) {
5201                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5202            }
5203            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5204                    + processName + " with config " + mConfiguration);
5205            ApplicationInfo appInfo = app.instrumentationInfo != null
5206                    ? app.instrumentationInfo : app.info;
5207            app.compat = compatibilityInfoForPackageLocked(appInfo);
5208            if (profileFd != null) {
5209                profileFd = profileFd.dup();
5210            }
5211            thread.bindApplication(processName, appInfo, providers,
5212                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5213                    app.instrumentationArguments, app.instrumentationWatcher,
5214                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5215                    isRestrictedBackupMode || !normalMode, app.persistent,
5216                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5217                    mCoreSettingsObserver.getCoreSettingsLocked());
5218            updateLruProcessLocked(app, false, null);
5219            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5220        } catch (Exception e) {
5221            // todo: Yikes!  What should we do?  For now we will try to
5222            // start another process, but that could easily get us in
5223            // an infinite loop of restarting processes...
5224            Slog.w(TAG, "Exception thrown during bind!", e);
5225
5226            app.resetPackageList(mProcessStats);
5227            app.unlinkDeathRecipient();
5228            startProcessLocked(app, "bind fail", processName);
5229            return false;
5230        }
5231
5232        // Remove this record from the list of starting applications.
5233        mPersistentStartingProcesses.remove(app);
5234        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5235                "Attach application locked removing on hold: " + app);
5236        mProcessesOnHold.remove(app);
5237
5238        boolean badApp = false;
5239        boolean didSomething = false;
5240
5241        // See if the top visible activity is waiting to run in this process...
5242        if (normalMode) {
5243            try {
5244                if (mStackSupervisor.attachApplicationLocked(app)) {
5245                    didSomething = true;
5246                }
5247            } catch (Exception e) {
5248                badApp = true;
5249            }
5250        }
5251
5252        // Find any services that should be running in this process...
5253        if (!badApp) {
5254            try {
5255                didSomething |= mServices.attachApplicationLocked(app, processName);
5256            } catch (Exception e) {
5257                badApp = true;
5258            }
5259        }
5260
5261        // Check if a next-broadcast receiver is in this process...
5262        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5263            try {
5264                didSomething |= sendPendingBroadcastsLocked(app);
5265            } catch (Exception e) {
5266                // If the app died trying to launch the receiver we declare it 'bad'
5267                badApp = true;
5268            }
5269        }
5270
5271        // Check whether the next backup agent is in this process...
5272        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5273            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5274            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5275            try {
5276                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5277                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5278                        mBackupTarget.backupMode);
5279            } catch (Exception e) {
5280                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5281                e.printStackTrace();
5282            }
5283        }
5284
5285        if (badApp) {
5286            // todo: Also need to kill application to deal with all
5287            // kinds of exceptions.
5288            handleAppDiedLocked(app, false, true);
5289            return false;
5290        }
5291
5292        if (!didSomething) {
5293            updateOomAdjLocked();
5294        }
5295
5296        return true;
5297    }
5298
5299    @Override
5300    public final void attachApplication(IApplicationThread thread) {
5301        synchronized (this) {
5302            int callingPid = Binder.getCallingPid();
5303            final long origId = Binder.clearCallingIdentity();
5304            attachApplicationLocked(thread, callingPid);
5305            Binder.restoreCallingIdentity(origId);
5306        }
5307    }
5308
5309    @Override
5310    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5311        final long origId = Binder.clearCallingIdentity();
5312        synchronized (this) {
5313            ActivityStack stack = ActivityRecord.getStackLocked(token);
5314            if (stack != null) {
5315                ActivityRecord r =
5316                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5317                if (stopProfiling) {
5318                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5319                        try {
5320                            mProfileFd.close();
5321                        } catch (IOException e) {
5322                        }
5323                        clearProfilerLocked();
5324                    }
5325                }
5326            }
5327        }
5328        Binder.restoreCallingIdentity(origId);
5329    }
5330
5331    void enableScreenAfterBoot() {
5332        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5333                SystemClock.uptimeMillis());
5334        mWindowManager.enableScreenAfterBoot();
5335
5336        synchronized (this) {
5337            updateEventDispatchingLocked();
5338        }
5339    }
5340
5341    @Override
5342    public void showBootMessage(final CharSequence msg, final boolean always) {
5343        enforceNotIsolatedCaller("showBootMessage");
5344        mWindowManager.showBootMessage(msg, always);
5345    }
5346
5347    @Override
5348    public void dismissKeyguardOnNextActivity() {
5349        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5350        final long token = Binder.clearCallingIdentity();
5351        try {
5352            synchronized (this) {
5353                if (DEBUG_LOCKSCREEN) logLockScreen("");
5354                if (mLockScreenShown) {
5355                    mLockScreenShown = false;
5356                    comeOutOfSleepIfNeededLocked();
5357                }
5358                mStackSupervisor.setDismissKeyguard(true);
5359            }
5360        } finally {
5361            Binder.restoreCallingIdentity(token);
5362        }
5363    }
5364
5365    final void finishBooting() {
5366        // Register receivers to handle package update events
5367        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5368
5369        synchronized (this) {
5370            // Ensure that any processes we had put on hold are now started
5371            // up.
5372            final int NP = mProcessesOnHold.size();
5373            if (NP > 0) {
5374                ArrayList<ProcessRecord> procs =
5375                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5376                for (int ip=0; ip<NP; ip++) {
5377                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5378                            + procs.get(ip));
5379                    startProcessLocked(procs.get(ip), "on-hold", null);
5380                }
5381            }
5382
5383            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5384                // Start looking for apps that are abusing wake locks.
5385                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5386                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5387                // Tell anyone interested that we are done booting!
5388                SystemProperties.set("sys.boot_completed", "1");
5389                SystemProperties.set("dev.bootcomplete", "1");
5390                for (int i=0; i<mStartedUsers.size(); i++) {
5391                    UserStartedState uss = mStartedUsers.valueAt(i);
5392                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5393                        uss.mState = UserStartedState.STATE_RUNNING;
5394                        final int userId = mStartedUsers.keyAt(i);
5395                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5396                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5397                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5398                        broadcastIntentLocked(null, null, intent, null,
5399                                new IIntentReceiver.Stub() {
5400                                    @Override
5401                                    public void performReceive(Intent intent, int resultCode,
5402                                            String data, Bundle extras, boolean ordered,
5403                                            boolean sticky, int sendingUser) {
5404                                        synchronized (ActivityManagerService.this) {
5405                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5406                                                    true, false);
5407                                        }
5408                                    }
5409                                },
5410                                0, null, null,
5411                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5412                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5413                                userId);
5414                    }
5415                }
5416                scheduleStartProfilesLocked();
5417            }
5418        }
5419    }
5420
5421    final void ensureBootCompleted() {
5422        boolean booting;
5423        boolean enableScreen;
5424        synchronized (this) {
5425            booting = mBooting;
5426            mBooting = false;
5427            enableScreen = !mBooted;
5428            mBooted = true;
5429        }
5430
5431        if (booting) {
5432            finishBooting();
5433        }
5434
5435        if (enableScreen) {
5436            enableScreenAfterBoot();
5437        }
5438    }
5439
5440    @Override
5441    public final void activityResumed(IBinder token) {
5442        final long origId = Binder.clearCallingIdentity();
5443        synchronized(this) {
5444            ActivityStack stack = ActivityRecord.getStackLocked(token);
5445            if (stack != null) {
5446                ActivityRecord.activityResumedLocked(token);
5447            }
5448        }
5449        Binder.restoreCallingIdentity(origId);
5450    }
5451
5452    @Override
5453    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5454        final long origId = Binder.clearCallingIdentity();
5455        synchronized(this) {
5456            ActivityStack stack = ActivityRecord.getStackLocked(token);
5457            if (stack != null) {
5458                stack.activityPausedLocked(token, false, persistentState);
5459            }
5460        }
5461        Binder.restoreCallingIdentity(origId);
5462    }
5463
5464    @Override
5465    public final void activityStopped(IBinder token, Bundle icicle,
5466            PersistableBundle persistentState, CharSequence description) {
5467        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5468
5469        // Refuse possible leaked file descriptors
5470        if (icicle != null && icicle.hasFileDescriptors()) {
5471            throw new IllegalArgumentException("File descriptors passed in Bundle");
5472        }
5473
5474        final long origId = Binder.clearCallingIdentity();
5475
5476        synchronized (this) {
5477            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5478            if (r != null) {
5479                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5480            }
5481        }
5482
5483        trimApplications();
5484
5485        Binder.restoreCallingIdentity(origId);
5486    }
5487
5488    @Override
5489    public final void activityDestroyed(IBinder token) {
5490        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5491        synchronized (this) {
5492            ActivityStack stack = ActivityRecord.getStackLocked(token);
5493            if (stack != null) {
5494                stack.activityDestroyedLocked(token);
5495            }
5496        }
5497    }
5498
5499    @Override
5500    public String getCallingPackage(IBinder token) {
5501        synchronized (this) {
5502            ActivityRecord r = getCallingRecordLocked(token);
5503            return r != null ? r.info.packageName : null;
5504        }
5505    }
5506
5507    @Override
5508    public ComponentName getCallingActivity(IBinder token) {
5509        synchronized (this) {
5510            ActivityRecord r = getCallingRecordLocked(token);
5511            return r != null ? r.intent.getComponent() : null;
5512        }
5513    }
5514
5515    private ActivityRecord getCallingRecordLocked(IBinder token) {
5516        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5517        if (r == null) {
5518            return null;
5519        }
5520        return r.resultTo;
5521    }
5522
5523    @Override
5524    public ComponentName getActivityClassForToken(IBinder token) {
5525        synchronized(this) {
5526            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5527            if (r == null) {
5528                return null;
5529            }
5530            return r.intent.getComponent();
5531        }
5532    }
5533
5534    @Override
5535    public String getPackageForToken(IBinder token) {
5536        synchronized(this) {
5537            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5538            if (r == null) {
5539                return null;
5540            }
5541            return r.packageName;
5542        }
5543    }
5544
5545    @Override
5546    public IIntentSender getIntentSender(int type,
5547            String packageName, IBinder token, String resultWho,
5548            int requestCode, Intent[] intents, String[] resolvedTypes,
5549            int flags, Bundle options, int userId) {
5550        enforceNotIsolatedCaller("getIntentSender");
5551        // Refuse possible leaked file descriptors
5552        if (intents != null) {
5553            if (intents.length < 1) {
5554                throw new IllegalArgumentException("Intents array length must be >= 1");
5555            }
5556            for (int i=0; i<intents.length; i++) {
5557                Intent intent = intents[i];
5558                if (intent != null) {
5559                    if (intent.hasFileDescriptors()) {
5560                        throw new IllegalArgumentException("File descriptors passed in Intent");
5561                    }
5562                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5563                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5564                        throw new IllegalArgumentException(
5565                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5566                    }
5567                    intents[i] = new Intent(intent);
5568                }
5569            }
5570            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5571                throw new IllegalArgumentException(
5572                        "Intent array length does not match resolvedTypes length");
5573            }
5574        }
5575        if (options != null) {
5576            if (options.hasFileDescriptors()) {
5577                throw new IllegalArgumentException("File descriptors passed in options");
5578            }
5579        }
5580
5581        synchronized(this) {
5582            int callingUid = Binder.getCallingUid();
5583            int origUserId = userId;
5584            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5585                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5586                    "getIntentSender", null);
5587            if (origUserId == UserHandle.USER_CURRENT) {
5588                // We don't want to evaluate this until the pending intent is
5589                // actually executed.  However, we do want to always do the
5590                // security checking for it above.
5591                userId = UserHandle.USER_CURRENT;
5592            }
5593            try {
5594                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5595                    int uid = AppGlobals.getPackageManager()
5596                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5597                    if (!UserHandle.isSameApp(callingUid, uid)) {
5598                        String msg = "Permission Denial: getIntentSender() from pid="
5599                            + Binder.getCallingPid()
5600                            + ", uid=" + Binder.getCallingUid()
5601                            + ", (need uid=" + uid + ")"
5602                            + " is not allowed to send as package " + packageName;
5603                        Slog.w(TAG, msg);
5604                        throw new SecurityException(msg);
5605                    }
5606                }
5607
5608                return getIntentSenderLocked(type, packageName, callingUid, userId,
5609                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5610
5611            } catch (RemoteException e) {
5612                throw new SecurityException(e);
5613            }
5614        }
5615    }
5616
5617    IIntentSender getIntentSenderLocked(int type, String packageName,
5618            int callingUid, int userId, IBinder token, String resultWho,
5619            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5620            Bundle options) {
5621        if (DEBUG_MU)
5622            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5623        ActivityRecord activity = null;
5624        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5625            activity = ActivityRecord.isInStackLocked(token);
5626            if (activity == null) {
5627                return null;
5628            }
5629            if (activity.finishing) {
5630                return null;
5631            }
5632        }
5633
5634        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5635        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5636        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5637        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5638                |PendingIntent.FLAG_UPDATE_CURRENT);
5639
5640        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5641                type, packageName, activity, resultWho,
5642                requestCode, intents, resolvedTypes, flags, options, userId);
5643        WeakReference<PendingIntentRecord> ref;
5644        ref = mIntentSenderRecords.get(key);
5645        PendingIntentRecord rec = ref != null ? ref.get() : null;
5646        if (rec != null) {
5647            if (!cancelCurrent) {
5648                if (updateCurrent) {
5649                    if (rec.key.requestIntent != null) {
5650                        rec.key.requestIntent.replaceExtras(intents != null ?
5651                                intents[intents.length - 1] : null);
5652                    }
5653                    if (intents != null) {
5654                        intents[intents.length-1] = rec.key.requestIntent;
5655                        rec.key.allIntents = intents;
5656                        rec.key.allResolvedTypes = resolvedTypes;
5657                    } else {
5658                        rec.key.allIntents = null;
5659                        rec.key.allResolvedTypes = null;
5660                    }
5661                }
5662                return rec;
5663            }
5664            rec.canceled = true;
5665            mIntentSenderRecords.remove(key);
5666        }
5667        if (noCreate) {
5668            return rec;
5669        }
5670        rec = new PendingIntentRecord(this, key, callingUid);
5671        mIntentSenderRecords.put(key, rec.ref);
5672        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5673            if (activity.pendingResults == null) {
5674                activity.pendingResults
5675                        = new HashSet<WeakReference<PendingIntentRecord>>();
5676            }
5677            activity.pendingResults.add(rec.ref);
5678        }
5679        return rec;
5680    }
5681
5682    @Override
5683    public void cancelIntentSender(IIntentSender sender) {
5684        if (!(sender instanceof PendingIntentRecord)) {
5685            return;
5686        }
5687        synchronized(this) {
5688            PendingIntentRecord rec = (PendingIntentRecord)sender;
5689            try {
5690                int uid = AppGlobals.getPackageManager()
5691                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5692                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5693                    String msg = "Permission Denial: cancelIntentSender() from pid="
5694                        + Binder.getCallingPid()
5695                        + ", uid=" + Binder.getCallingUid()
5696                        + " is not allowed to cancel packges "
5697                        + rec.key.packageName;
5698                    Slog.w(TAG, msg);
5699                    throw new SecurityException(msg);
5700                }
5701            } catch (RemoteException e) {
5702                throw new SecurityException(e);
5703            }
5704            cancelIntentSenderLocked(rec, true);
5705        }
5706    }
5707
5708    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5709        rec.canceled = true;
5710        mIntentSenderRecords.remove(rec.key);
5711        if (cleanActivity && rec.key.activity != null) {
5712            rec.key.activity.pendingResults.remove(rec.ref);
5713        }
5714    }
5715
5716    @Override
5717    public String getPackageForIntentSender(IIntentSender pendingResult) {
5718        if (!(pendingResult instanceof PendingIntentRecord)) {
5719            return null;
5720        }
5721        try {
5722            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5723            return res.key.packageName;
5724        } catch (ClassCastException e) {
5725        }
5726        return null;
5727    }
5728
5729    @Override
5730    public int getUidForIntentSender(IIntentSender sender) {
5731        if (sender instanceof PendingIntentRecord) {
5732            try {
5733                PendingIntentRecord res = (PendingIntentRecord)sender;
5734                return res.uid;
5735            } catch (ClassCastException e) {
5736            }
5737        }
5738        return -1;
5739    }
5740
5741    @Override
5742    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5743        if (!(pendingResult instanceof PendingIntentRecord)) {
5744            return false;
5745        }
5746        try {
5747            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5748            if (res.key.allIntents == null) {
5749                return false;
5750            }
5751            for (int i=0; i<res.key.allIntents.length; i++) {
5752                Intent intent = res.key.allIntents[i];
5753                if (intent.getPackage() != null && intent.getComponent() != null) {
5754                    return false;
5755                }
5756            }
5757            return true;
5758        } catch (ClassCastException e) {
5759        }
5760        return false;
5761    }
5762
5763    @Override
5764    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5765        if (!(pendingResult instanceof PendingIntentRecord)) {
5766            return false;
5767        }
5768        try {
5769            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5770            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5771                return true;
5772            }
5773            return false;
5774        } catch (ClassCastException e) {
5775        }
5776        return false;
5777    }
5778
5779    @Override
5780    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5781        if (!(pendingResult instanceof PendingIntentRecord)) {
5782            return null;
5783        }
5784        try {
5785            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5786            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5787        } catch (ClassCastException e) {
5788        }
5789        return null;
5790    }
5791
5792    @Override
5793    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5794        if (!(pendingResult instanceof PendingIntentRecord)) {
5795            return null;
5796        }
5797        try {
5798            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5799            Intent intent = res.key.requestIntent;
5800            if (intent != null) {
5801                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5802                        || res.lastTagPrefix.equals(prefix))) {
5803                    return res.lastTag;
5804                }
5805                res.lastTagPrefix = prefix;
5806                StringBuilder sb = new StringBuilder(128);
5807                if (prefix != null) {
5808                    sb.append(prefix);
5809                }
5810                if (intent.getAction() != null) {
5811                    sb.append(intent.getAction());
5812                } else if (intent.getComponent() != null) {
5813                    intent.getComponent().appendShortString(sb);
5814                } else {
5815                    sb.append("?");
5816                }
5817                return res.lastTag = sb.toString();
5818            }
5819        } catch (ClassCastException e) {
5820        }
5821        return null;
5822    }
5823
5824    @Override
5825    public void setProcessLimit(int max) {
5826        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5827                "setProcessLimit()");
5828        synchronized (this) {
5829            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5830            mProcessLimitOverride = max;
5831        }
5832        trimApplications();
5833    }
5834
5835    @Override
5836    public int getProcessLimit() {
5837        synchronized (this) {
5838            return mProcessLimitOverride;
5839        }
5840    }
5841
5842    void foregroundTokenDied(ForegroundToken token) {
5843        synchronized (ActivityManagerService.this) {
5844            synchronized (mPidsSelfLocked) {
5845                ForegroundToken cur
5846                    = mForegroundProcesses.get(token.pid);
5847                if (cur != token) {
5848                    return;
5849                }
5850                mForegroundProcesses.remove(token.pid);
5851                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5852                if (pr == null) {
5853                    return;
5854                }
5855                pr.forcingToForeground = null;
5856                updateProcessForegroundLocked(pr, false, false);
5857            }
5858            updateOomAdjLocked();
5859        }
5860    }
5861
5862    @Override
5863    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5864        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5865                "setProcessForeground()");
5866        synchronized(this) {
5867            boolean changed = false;
5868
5869            synchronized (mPidsSelfLocked) {
5870                ProcessRecord pr = mPidsSelfLocked.get(pid);
5871                if (pr == null && isForeground) {
5872                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5873                    return;
5874                }
5875                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5876                if (oldToken != null) {
5877                    oldToken.token.unlinkToDeath(oldToken, 0);
5878                    mForegroundProcesses.remove(pid);
5879                    if (pr != null) {
5880                        pr.forcingToForeground = null;
5881                    }
5882                    changed = true;
5883                }
5884                if (isForeground && token != null) {
5885                    ForegroundToken newToken = new ForegroundToken() {
5886                        @Override
5887                        public void binderDied() {
5888                            foregroundTokenDied(this);
5889                        }
5890                    };
5891                    newToken.pid = pid;
5892                    newToken.token = token;
5893                    try {
5894                        token.linkToDeath(newToken, 0);
5895                        mForegroundProcesses.put(pid, newToken);
5896                        pr.forcingToForeground = token;
5897                        changed = true;
5898                    } catch (RemoteException e) {
5899                        // If the process died while doing this, we will later
5900                        // do the cleanup with the process death link.
5901                    }
5902                }
5903            }
5904
5905            if (changed) {
5906                updateOomAdjLocked();
5907            }
5908        }
5909    }
5910
5911    // =========================================================
5912    // PERMISSIONS
5913    // =========================================================
5914
5915    static class PermissionController extends IPermissionController.Stub {
5916        ActivityManagerService mActivityManagerService;
5917        PermissionController(ActivityManagerService activityManagerService) {
5918            mActivityManagerService = activityManagerService;
5919        }
5920
5921        @Override
5922        public boolean checkPermission(String permission, int pid, int uid) {
5923            return mActivityManagerService.checkPermission(permission, pid,
5924                    uid) == PackageManager.PERMISSION_GRANTED;
5925        }
5926    }
5927
5928    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5929        @Override
5930        public int checkComponentPermission(String permission, int pid, int uid,
5931                int owningUid, boolean exported) {
5932            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5933                    owningUid, exported);
5934        }
5935
5936        @Override
5937        public Object getAMSLock() {
5938            return ActivityManagerService.this;
5939        }
5940    }
5941
5942    /**
5943     * This can be called with or without the global lock held.
5944     */
5945    int checkComponentPermission(String permission, int pid, int uid,
5946            int owningUid, boolean exported) {
5947        // We might be performing an operation on behalf of an indirect binder
5948        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5949        // client identity accordingly before proceeding.
5950        Identity tlsIdentity = sCallerIdentity.get();
5951        if (tlsIdentity != null) {
5952            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5953                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5954            uid = tlsIdentity.uid;
5955            pid = tlsIdentity.pid;
5956        }
5957
5958        if (pid == MY_PID) {
5959            return PackageManager.PERMISSION_GRANTED;
5960        }
5961
5962        return ActivityManager.checkComponentPermission(permission, uid,
5963                owningUid, exported);
5964    }
5965
5966    /**
5967     * As the only public entry point for permissions checking, this method
5968     * can enforce the semantic that requesting a check on a null global
5969     * permission is automatically denied.  (Internally a null permission
5970     * string is used when calling {@link #checkComponentPermission} in cases
5971     * when only uid-based security is needed.)
5972     *
5973     * This can be called with or without the global lock held.
5974     */
5975    @Override
5976    public int checkPermission(String permission, int pid, int uid) {
5977        if (permission == null) {
5978            return PackageManager.PERMISSION_DENIED;
5979        }
5980        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5981    }
5982
5983    /**
5984     * Binder IPC calls go through the public entry point.
5985     * This can be called with or without the global lock held.
5986     */
5987    int checkCallingPermission(String permission) {
5988        return checkPermission(permission,
5989                Binder.getCallingPid(),
5990                UserHandle.getAppId(Binder.getCallingUid()));
5991    }
5992
5993    /**
5994     * This can be called with or without the global lock held.
5995     */
5996    void enforceCallingPermission(String permission, String func) {
5997        if (checkCallingPermission(permission)
5998                == PackageManager.PERMISSION_GRANTED) {
5999            return;
6000        }
6001
6002        String msg = "Permission Denial: " + func + " from pid="
6003                + Binder.getCallingPid()
6004                + ", uid=" + Binder.getCallingUid()
6005                + " requires " + permission;
6006        Slog.w(TAG, msg);
6007        throw new SecurityException(msg);
6008    }
6009
6010    /**
6011     * Determine if UID is holding permissions required to access {@link Uri} in
6012     * the given {@link ProviderInfo}. Final permission checking is always done
6013     * in {@link ContentProvider}.
6014     */
6015    private final boolean checkHoldingPermissionsLocked(
6016            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6017        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6018                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6019
6020        if (pi.applicationInfo.uid == uid) {
6021            return true;
6022        } else if (!pi.exported) {
6023            return false;
6024        }
6025
6026        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6027        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6028        try {
6029            // check if target holds top-level <provider> permissions
6030            if (!readMet && pi.readPermission != null
6031                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6032                readMet = true;
6033            }
6034            if (!writeMet && pi.writePermission != null
6035                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6036                writeMet = true;
6037            }
6038
6039            // track if unprotected read/write is allowed; any denied
6040            // <path-permission> below removes this ability
6041            boolean allowDefaultRead = pi.readPermission == null;
6042            boolean allowDefaultWrite = pi.writePermission == null;
6043
6044            // check if target holds any <path-permission> that match uri
6045            final PathPermission[] pps = pi.pathPermissions;
6046            if (pps != null) {
6047                final String path = grantUri.uri.getPath();
6048                int i = pps.length;
6049                while (i > 0 && (!readMet || !writeMet)) {
6050                    i--;
6051                    PathPermission pp = pps[i];
6052                    if (pp.match(path)) {
6053                        if (!readMet) {
6054                            final String pprperm = pp.getReadPermission();
6055                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6056                                    + pprperm + " for " + pp.getPath()
6057                                    + ": match=" + pp.match(path)
6058                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6059                            if (pprperm != null) {
6060                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6061                                    readMet = true;
6062                                } else {
6063                                    allowDefaultRead = false;
6064                                }
6065                            }
6066                        }
6067                        if (!writeMet) {
6068                            final String ppwperm = pp.getWritePermission();
6069                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6070                                    + ppwperm + " for " + pp.getPath()
6071                                    + ": match=" + pp.match(path)
6072                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6073                            if (ppwperm != null) {
6074                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6075                                    writeMet = true;
6076                                } else {
6077                                    allowDefaultWrite = false;
6078                                }
6079                            }
6080                        }
6081                    }
6082                }
6083            }
6084
6085            // grant unprotected <provider> read/write, if not blocked by
6086            // <path-permission> above
6087            if (allowDefaultRead) readMet = true;
6088            if (allowDefaultWrite) writeMet = true;
6089
6090        } catch (RemoteException e) {
6091            return false;
6092        }
6093
6094        return readMet && writeMet;
6095    }
6096
6097    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6098        ProviderInfo pi = null;
6099        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6100        if (cpr != null) {
6101            pi = cpr.info;
6102        } else {
6103            try {
6104                pi = AppGlobals.getPackageManager().resolveContentProvider(
6105                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6106            } catch (RemoteException ex) {
6107            }
6108        }
6109        return pi;
6110    }
6111
6112    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6113        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6114        if (targetUris != null) {
6115            return targetUris.get(grantUri);
6116        }
6117        return null;
6118    }
6119
6120    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6121            String targetPkg, int targetUid, GrantUri grantUri) {
6122        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6123        if (targetUris == null) {
6124            targetUris = Maps.newArrayMap();
6125            mGrantedUriPermissions.put(targetUid, targetUris);
6126        }
6127
6128        UriPermission perm = targetUris.get(grantUri);
6129        if (perm == null) {
6130            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6131            targetUris.put(grantUri, perm);
6132        }
6133
6134        return perm;
6135    }
6136
6137    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6138            final int modeFlags) {
6139        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6140        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6141                : UriPermission.STRENGTH_OWNED;
6142
6143        // Root gets to do everything.
6144        if (uid == 0) {
6145            return true;
6146        }
6147
6148        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6149        if (perms == null) return false;
6150
6151        // First look for exact match
6152        final UriPermission exactPerm = perms.get(grantUri);
6153        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6154            return true;
6155        }
6156
6157        // No exact match, look for prefixes
6158        final int N = perms.size();
6159        for (int i = 0; i < N; i++) {
6160            final UriPermission perm = perms.valueAt(i);
6161            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6162                    && perm.getStrength(modeFlags) >= minStrength) {
6163                return true;
6164            }
6165        }
6166
6167        return false;
6168    }
6169
6170    @Override
6171    public int checkUriPermission(Uri uri, int pid, int uid,
6172            final int modeFlags, int userId) {
6173        enforceNotIsolatedCaller("checkUriPermission");
6174
6175        // Another redirected-binder-call permissions check as in
6176        // {@link checkComponentPermission}.
6177        Identity tlsIdentity = sCallerIdentity.get();
6178        if (tlsIdentity != null) {
6179            uid = tlsIdentity.uid;
6180            pid = tlsIdentity.pid;
6181        }
6182
6183        // Our own process gets to do everything.
6184        if (pid == MY_PID) {
6185            return PackageManager.PERMISSION_GRANTED;
6186        }
6187        synchronized (this) {
6188            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6189                    ? PackageManager.PERMISSION_GRANTED
6190                    : PackageManager.PERMISSION_DENIED;
6191        }
6192    }
6193
6194    /**
6195     * Check if the targetPkg can be granted permission to access uri by
6196     * the callingUid using the given modeFlags.  Throws a security exception
6197     * if callingUid is not allowed to do this.  Returns the uid of the target
6198     * if the URI permission grant should be performed; returns -1 if it is not
6199     * needed (for example targetPkg already has permission to access the URI).
6200     * If you already know the uid of the target, you can supply it in
6201     * lastTargetUid else set that to -1.
6202     */
6203    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6204            final int modeFlags, int lastTargetUid) {
6205        if (!Intent.isAccessUriMode(modeFlags)) {
6206            return -1;
6207        }
6208
6209        if (targetPkg != null) {
6210            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6211                    "Checking grant " + targetPkg + " permission to " + grantUri);
6212        }
6213
6214        final IPackageManager pm = AppGlobals.getPackageManager();
6215
6216        // If this is not a content: uri, we can't do anything with it.
6217        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6218            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6219                    "Can't grant URI permission for non-content URI: " + grantUri);
6220            return -1;
6221        }
6222
6223        final String authority = grantUri.uri.getAuthority();
6224        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6225        if (pi == null) {
6226            Slog.w(TAG, "No content provider found for permission check: " +
6227                    grantUri.uri.toSafeString());
6228            return -1;
6229        }
6230
6231        int targetUid = lastTargetUid;
6232        if (targetUid < 0 && targetPkg != null) {
6233            try {
6234                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6235                if (targetUid < 0) {
6236                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6237                            "Can't grant URI permission no uid for: " + targetPkg);
6238                    return -1;
6239                }
6240            } catch (RemoteException ex) {
6241                return -1;
6242            }
6243        }
6244
6245        if (targetUid >= 0) {
6246            // First...  does the target actually need this permission?
6247            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6248                // No need to grant the target this permission.
6249                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6250                        "Target " + targetPkg + " already has full permission to " + grantUri);
6251                return -1;
6252            }
6253        } else {
6254            // First...  there is no target package, so can anyone access it?
6255            boolean allowed = pi.exported;
6256            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6257                if (pi.readPermission != null) {
6258                    allowed = false;
6259                }
6260            }
6261            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6262                if (pi.writePermission != null) {
6263                    allowed = false;
6264                }
6265            }
6266            if (allowed) {
6267                return -1;
6268            }
6269        }
6270
6271        // Second...  is the provider allowing granting of URI permissions?
6272        if (!pi.grantUriPermissions) {
6273            throw new SecurityException("Provider " + pi.packageName
6274                    + "/" + pi.name
6275                    + " does not allow granting of Uri permissions (uri "
6276                    + grantUri + ")");
6277        }
6278        if (pi.uriPermissionPatterns != null) {
6279            final int N = pi.uriPermissionPatterns.length;
6280            boolean allowed = false;
6281            for (int i=0; i<N; i++) {
6282                if (pi.uriPermissionPatterns[i] != null
6283                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6284                    allowed = true;
6285                    break;
6286                }
6287            }
6288            if (!allowed) {
6289                throw new SecurityException("Provider " + pi.packageName
6290                        + "/" + pi.name
6291                        + " does not allow granting of permission to path of Uri "
6292                        + grantUri);
6293            }
6294        }
6295
6296        // Third...  does the caller itself have permission to access
6297        // this uri?
6298        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6299            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6300                // Require they hold a strong enough Uri permission
6301                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6302                    throw new SecurityException("Uid " + callingUid
6303                            + " does not have permission to uri " + grantUri);
6304                }
6305            }
6306        }
6307        return targetUid;
6308    }
6309
6310    @Override
6311    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6312            final int modeFlags, int userId) {
6313        enforceNotIsolatedCaller("checkGrantUriPermission");
6314        synchronized(this) {
6315            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6316                    new GrantUri(userId, uri, false), modeFlags, -1);
6317        }
6318    }
6319
6320    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6321            final int modeFlags, UriPermissionOwner owner) {
6322        if (!Intent.isAccessUriMode(modeFlags)) {
6323            return;
6324        }
6325
6326        // So here we are: the caller has the assumed permission
6327        // to the uri, and the target doesn't.  Let's now give this to
6328        // the target.
6329
6330        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6331                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6332
6333        final String authority = grantUri.uri.getAuthority();
6334        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6335        if (pi == null) {
6336            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6337            return;
6338        }
6339
6340        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6341            grantUri.prefix = true;
6342        }
6343        final UriPermission perm = findOrCreateUriPermissionLocked(
6344                pi.packageName, targetPkg, targetUid, grantUri);
6345        perm.grantModes(modeFlags, owner);
6346    }
6347
6348    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6349            final int modeFlags, UriPermissionOwner owner) {
6350        if (targetPkg == null) {
6351            throw new NullPointerException("targetPkg");
6352        }
6353
6354        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6355                -1);
6356        if (targetUid < 0) {
6357            return;
6358        }
6359
6360        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6361                owner);
6362    }
6363
6364    static class NeededUriGrants extends ArrayList<GrantUri> {
6365        final String targetPkg;
6366        final int targetUid;
6367        final int flags;
6368
6369        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6370            this.targetPkg = targetPkg;
6371            this.targetUid = targetUid;
6372            this.flags = flags;
6373        }
6374    }
6375
6376    /**
6377     * Like checkGrantUriPermissionLocked, but takes an Intent.
6378     */
6379    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6380            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6381        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6382                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6383                + " clip=" + (intent != null ? intent.getClipData() : null)
6384                + " from " + intent + "; flags=0x"
6385                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6386
6387        if (targetPkg == null) {
6388            throw new NullPointerException("targetPkg");
6389        }
6390
6391        if (intent == null) {
6392            return null;
6393        }
6394        Uri data = intent.getData();
6395        ClipData clip = intent.getClipData();
6396        if (data == null && clip == null) {
6397            return null;
6398        }
6399
6400        if (data != null) {
6401            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6402            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6403                    needed != null ? needed.targetUid : -1);
6404            if (targetUid > 0) {
6405                if (needed == null) {
6406                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6407                }
6408                needed.add(grantUri);
6409            }
6410        }
6411        if (clip != null) {
6412            for (int i=0; i<clip.getItemCount(); i++) {
6413                Uri uri = clip.getItemAt(i).getUri();
6414                if (uri != null) {
6415                    int targetUid = -1;
6416                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6417                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6418                            needed != null ? needed.targetUid : -1);
6419                    if (targetUid > 0) {
6420                        if (needed == null) {
6421                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6422                        }
6423                        needed.add(grantUri);
6424                    }
6425                } else {
6426                    Intent clipIntent = clip.getItemAt(i).getIntent();
6427                    if (clipIntent != null) {
6428                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6429                                callingUid, targetPkg, clipIntent, mode, needed);
6430                        if (newNeeded != null) {
6431                            needed = newNeeded;
6432                        }
6433                    }
6434                }
6435            }
6436        }
6437
6438        return needed;
6439    }
6440
6441    /**
6442     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6443     */
6444    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6445            UriPermissionOwner owner) {
6446        if (needed != null) {
6447            for (int i=0; i<needed.size(); i++) {
6448                GrantUri grantUri = needed.get(i);
6449                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6450                        grantUri, needed.flags, owner);
6451            }
6452        }
6453    }
6454
6455    void grantUriPermissionFromIntentLocked(int callingUid,
6456            String targetPkg, Intent intent, UriPermissionOwner owner) {
6457        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6458                intent, intent != null ? intent.getFlags() : 0, null);
6459        if (needed == null) {
6460            return;
6461        }
6462
6463        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6464    }
6465
6466    @Override
6467    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6468            final int modeFlags, int userId) {
6469        enforceNotIsolatedCaller("grantUriPermission");
6470        GrantUri grantUri = new GrantUri(userId, uri, false);
6471        synchronized(this) {
6472            final ProcessRecord r = getRecordForAppLocked(caller);
6473            if (r == null) {
6474                throw new SecurityException("Unable to find app for caller "
6475                        + caller
6476                        + " when granting permission to uri " + grantUri);
6477            }
6478            if (targetPkg == null) {
6479                throw new IllegalArgumentException("null target");
6480            }
6481            if (grantUri == null) {
6482                throw new IllegalArgumentException("null uri");
6483            }
6484
6485            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6486                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6487                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6488                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6489
6490            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6491        }
6492    }
6493
6494    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6495        if (perm.modeFlags == 0) {
6496            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6497                    perm.targetUid);
6498            if (perms != null) {
6499                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6500                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6501
6502                perms.remove(perm.uri);
6503                if (perms.isEmpty()) {
6504                    mGrantedUriPermissions.remove(perm.targetUid);
6505                }
6506            }
6507        }
6508    }
6509
6510    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6511        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6512
6513        final IPackageManager pm = AppGlobals.getPackageManager();
6514        final String authority = grantUri.uri.getAuthority();
6515        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6516        if (pi == null) {
6517            Slog.w(TAG, "No content provider found for permission revoke: "
6518                    + grantUri.toSafeString());
6519            return;
6520        }
6521
6522        // Does the caller have this permission on the URI?
6523        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6524            // Right now, if you are not the original owner of the permission,
6525            // you are not allowed to revoke it.
6526            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6527                throw new SecurityException("Uid " + callingUid
6528                        + " does not have permission to uri " + grantUri);
6529            //}
6530        }
6531
6532        boolean persistChanged = false;
6533
6534        // Go through all of the permissions and remove any that match.
6535        int N = mGrantedUriPermissions.size();
6536        for (int i = 0; i < N; i++) {
6537            final int targetUid = mGrantedUriPermissions.keyAt(i);
6538            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6539
6540            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6541                final UriPermission perm = it.next();
6542                if (perm.uri.sourceUserId == grantUri.sourceUserId
6543                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6544                    if (DEBUG_URI_PERMISSION)
6545                        Slog.v(TAG,
6546                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6547                    persistChanged |= perm.revokeModes(
6548                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6549                    if (perm.modeFlags == 0) {
6550                        it.remove();
6551                    }
6552                }
6553            }
6554
6555            if (perms.isEmpty()) {
6556                mGrantedUriPermissions.remove(targetUid);
6557                N--;
6558                i--;
6559            }
6560        }
6561
6562        if (persistChanged) {
6563            schedulePersistUriGrants();
6564        }
6565    }
6566
6567    @Override
6568    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6569            int userId) {
6570        enforceNotIsolatedCaller("revokeUriPermission");
6571        synchronized(this) {
6572            final ProcessRecord r = getRecordForAppLocked(caller);
6573            if (r == null) {
6574                throw new SecurityException("Unable to find app for caller "
6575                        + caller
6576                        + " when revoking permission to uri " + uri);
6577            }
6578            if (uri == null) {
6579                Slog.w(TAG, "revokeUriPermission: null uri");
6580                return;
6581            }
6582
6583            if (!Intent.isAccessUriMode(modeFlags)) {
6584                return;
6585            }
6586
6587            final IPackageManager pm = AppGlobals.getPackageManager();
6588            final String authority = uri.getAuthority();
6589            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6590            if (pi == null) {
6591                Slog.w(TAG, "No content provider found for permission revoke: "
6592                        + uri.toSafeString());
6593                return;
6594            }
6595
6596            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6597        }
6598    }
6599
6600    /**
6601     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6602     * given package.
6603     *
6604     * @param packageName Package name to match, or {@code null} to apply to all
6605     *            packages.
6606     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6607     *            to all users.
6608     * @param persistable If persistable grants should be removed.
6609     */
6610    private void removeUriPermissionsForPackageLocked(
6611            String packageName, int userHandle, boolean persistable) {
6612        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6613            throw new IllegalArgumentException("Must narrow by either package or user");
6614        }
6615
6616        boolean persistChanged = false;
6617
6618        int N = mGrantedUriPermissions.size();
6619        for (int i = 0; i < N; i++) {
6620            final int targetUid = mGrantedUriPermissions.keyAt(i);
6621            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6622
6623            // Only inspect grants matching user
6624            if (userHandle == UserHandle.USER_ALL
6625                    || userHandle == UserHandle.getUserId(targetUid)) {
6626                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6627                    final UriPermission perm = it.next();
6628
6629                    // Only inspect grants matching package
6630                    if (packageName == null || perm.sourcePkg.equals(packageName)
6631                            || perm.targetPkg.equals(packageName)) {
6632                        persistChanged |= perm.revokeModes(
6633                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6634
6635                        // Only remove when no modes remain; any persisted grants
6636                        // will keep this alive.
6637                        if (perm.modeFlags == 0) {
6638                            it.remove();
6639                        }
6640                    }
6641                }
6642
6643                if (perms.isEmpty()) {
6644                    mGrantedUriPermissions.remove(targetUid);
6645                    N--;
6646                    i--;
6647                }
6648            }
6649        }
6650
6651        if (persistChanged) {
6652            schedulePersistUriGrants();
6653        }
6654    }
6655
6656    @Override
6657    public IBinder newUriPermissionOwner(String name) {
6658        enforceNotIsolatedCaller("newUriPermissionOwner");
6659        synchronized(this) {
6660            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6661            return owner.getExternalTokenLocked();
6662        }
6663    }
6664
6665    @Override
6666    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6667            final int modeFlags, int userId) {
6668        synchronized(this) {
6669            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6670            if (owner == null) {
6671                throw new IllegalArgumentException("Unknown owner: " + token);
6672            }
6673            if (fromUid != Binder.getCallingUid()) {
6674                if (Binder.getCallingUid() != Process.myUid()) {
6675                    // Only system code can grant URI permissions on behalf
6676                    // of other users.
6677                    throw new SecurityException("nice try");
6678                }
6679            }
6680            if (targetPkg == null) {
6681                throw new IllegalArgumentException("null target");
6682            }
6683            if (uri == null) {
6684                throw new IllegalArgumentException("null uri");
6685            }
6686
6687            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6688                    modeFlags, owner);
6689        }
6690    }
6691
6692    @Override
6693    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6694        synchronized(this) {
6695            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6696            if (owner == null) {
6697                throw new IllegalArgumentException("Unknown owner: " + token);
6698            }
6699
6700            if (uri == null) {
6701                owner.removeUriPermissionsLocked(mode);
6702            } else {
6703                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6704            }
6705        }
6706    }
6707
6708    private void schedulePersistUriGrants() {
6709        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6710            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6711                    10 * DateUtils.SECOND_IN_MILLIS);
6712        }
6713    }
6714
6715    private void writeGrantedUriPermissions() {
6716        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6717
6718        // Snapshot permissions so we can persist without lock
6719        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6720        synchronized (this) {
6721            final int size = mGrantedUriPermissions.size();
6722            for (int i = 0; i < size; i++) {
6723                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6724                for (UriPermission perm : perms.values()) {
6725                    if (perm.persistedModeFlags != 0) {
6726                        persist.add(perm.snapshot());
6727                    }
6728                }
6729            }
6730        }
6731
6732        FileOutputStream fos = null;
6733        try {
6734            fos = mGrantFile.startWrite();
6735
6736            XmlSerializer out = new FastXmlSerializer();
6737            out.setOutput(fos, "utf-8");
6738            out.startDocument(null, true);
6739            out.startTag(null, TAG_URI_GRANTS);
6740            for (UriPermission.Snapshot perm : persist) {
6741                out.startTag(null, TAG_URI_GRANT);
6742                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6743                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6744                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6745                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6746                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6747                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6748                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6749                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6750                out.endTag(null, TAG_URI_GRANT);
6751            }
6752            out.endTag(null, TAG_URI_GRANTS);
6753            out.endDocument();
6754
6755            mGrantFile.finishWrite(fos);
6756        } catch (IOException e) {
6757            if (fos != null) {
6758                mGrantFile.failWrite(fos);
6759            }
6760        }
6761    }
6762
6763    private void readGrantedUriPermissionsLocked() {
6764        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6765
6766        final long now = System.currentTimeMillis();
6767
6768        FileInputStream fis = null;
6769        try {
6770            fis = mGrantFile.openRead();
6771            final XmlPullParser in = Xml.newPullParser();
6772            in.setInput(fis, null);
6773
6774            int type;
6775            while ((type = in.next()) != END_DOCUMENT) {
6776                final String tag = in.getName();
6777                if (type == START_TAG) {
6778                    if (TAG_URI_GRANT.equals(tag)) {
6779                        final int sourceUserId;
6780                        final int targetUserId;
6781                        final int userHandle = readIntAttribute(in,
6782                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6783                        if (userHandle != UserHandle.USER_NULL) {
6784                            // For backwards compatibility.
6785                            sourceUserId = userHandle;
6786                            targetUserId = userHandle;
6787                        } else {
6788                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6789                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6790                        }
6791                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6792                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6793                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6794                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6795                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6796                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6797
6798                        // Sanity check that provider still belongs to source package
6799                        final ProviderInfo pi = getProviderInfoLocked(
6800                                uri.getAuthority(), sourceUserId);
6801                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6802                            int targetUid = -1;
6803                            try {
6804                                targetUid = AppGlobals.getPackageManager()
6805                                        .getPackageUid(targetPkg, targetUserId);
6806                            } catch (RemoteException e) {
6807                            }
6808                            if (targetUid != -1) {
6809                                final UriPermission perm = findOrCreateUriPermissionLocked(
6810                                        sourcePkg, targetPkg, targetUid,
6811                                        new GrantUri(sourceUserId, uri, prefix));
6812                                perm.initPersistedModes(modeFlags, createdTime);
6813                            }
6814                        } else {
6815                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6816                                    + " but instead found " + pi);
6817                        }
6818                    }
6819                }
6820            }
6821        } catch (FileNotFoundException e) {
6822            // Missing grants is okay
6823        } catch (IOException e) {
6824            Log.wtf(TAG, "Failed reading Uri grants", e);
6825        } catch (XmlPullParserException e) {
6826            Log.wtf(TAG, "Failed reading Uri grants", e);
6827        } finally {
6828            IoUtils.closeQuietly(fis);
6829        }
6830    }
6831
6832    @Override
6833    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6834        enforceNotIsolatedCaller("takePersistableUriPermission");
6835
6836        Preconditions.checkFlagsArgument(modeFlags,
6837                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6838
6839        synchronized (this) {
6840            final int callingUid = Binder.getCallingUid();
6841            boolean persistChanged = false;
6842            GrantUri grantUri = new GrantUri(userId, uri, false);
6843
6844            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6845                    new GrantUri(userId, uri, false));
6846            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6847                    new GrantUri(userId, uri, true));
6848
6849            final boolean exactValid = (exactPerm != null)
6850                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6851            final boolean prefixValid = (prefixPerm != null)
6852                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6853
6854            if (!(exactValid || prefixValid)) {
6855                throw new SecurityException("No persistable permission grants found for UID "
6856                        + callingUid + " and Uri " + grantUri.toSafeString());
6857            }
6858
6859            if (exactValid) {
6860                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6861            }
6862            if (prefixValid) {
6863                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6864            }
6865
6866            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6867
6868            if (persistChanged) {
6869                schedulePersistUriGrants();
6870            }
6871        }
6872    }
6873
6874    @Override
6875    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6876        enforceNotIsolatedCaller("releasePersistableUriPermission");
6877
6878        Preconditions.checkFlagsArgument(modeFlags,
6879                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6880
6881        synchronized (this) {
6882            final int callingUid = Binder.getCallingUid();
6883            boolean persistChanged = false;
6884
6885            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6886                    new GrantUri(userId, uri, false));
6887            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6888                    new GrantUri(userId, uri, true));
6889            if (exactPerm == null && prefixPerm == null) {
6890                throw new SecurityException("No permission grants found for UID " + callingUid
6891                        + " and Uri " + uri.toSafeString());
6892            }
6893
6894            if (exactPerm != null) {
6895                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6896                removeUriPermissionIfNeededLocked(exactPerm);
6897            }
6898            if (prefixPerm != null) {
6899                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6900                removeUriPermissionIfNeededLocked(prefixPerm);
6901            }
6902
6903            if (persistChanged) {
6904                schedulePersistUriGrants();
6905            }
6906        }
6907    }
6908
6909    /**
6910     * Prune any older {@link UriPermission} for the given UID until outstanding
6911     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6912     *
6913     * @return if any mutations occured that require persisting.
6914     */
6915    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6916        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6917        if (perms == null) return false;
6918        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6919
6920        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6921        for (UriPermission perm : perms.values()) {
6922            if (perm.persistedModeFlags != 0) {
6923                persisted.add(perm);
6924            }
6925        }
6926
6927        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6928        if (trimCount <= 0) return false;
6929
6930        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6931        for (int i = 0; i < trimCount; i++) {
6932            final UriPermission perm = persisted.get(i);
6933
6934            if (DEBUG_URI_PERMISSION) {
6935                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6936            }
6937
6938            perm.releasePersistableModes(~0);
6939            removeUriPermissionIfNeededLocked(perm);
6940        }
6941
6942        return true;
6943    }
6944
6945    @Override
6946    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6947            String packageName, boolean incoming) {
6948        enforceNotIsolatedCaller("getPersistedUriPermissions");
6949        Preconditions.checkNotNull(packageName, "packageName");
6950
6951        final int callingUid = Binder.getCallingUid();
6952        final IPackageManager pm = AppGlobals.getPackageManager();
6953        try {
6954            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6955            if (packageUid != callingUid) {
6956                throw new SecurityException(
6957                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6958            }
6959        } catch (RemoteException e) {
6960            throw new SecurityException("Failed to verify package name ownership");
6961        }
6962
6963        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6964        synchronized (this) {
6965            if (incoming) {
6966                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6967                        callingUid);
6968                if (perms == null) {
6969                    Slog.w(TAG, "No permission grants found for " + packageName);
6970                } else {
6971                    for (UriPermission perm : perms.values()) {
6972                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6973                            result.add(perm.buildPersistedPublicApiObject());
6974                        }
6975                    }
6976                }
6977            } else {
6978                final int size = mGrantedUriPermissions.size();
6979                for (int i = 0; i < size; i++) {
6980                    final ArrayMap<GrantUri, UriPermission> perms =
6981                            mGrantedUriPermissions.valueAt(i);
6982                    for (UriPermission perm : perms.values()) {
6983                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6984                            result.add(perm.buildPersistedPublicApiObject());
6985                        }
6986                    }
6987                }
6988            }
6989        }
6990        return new ParceledListSlice<android.content.UriPermission>(result);
6991    }
6992
6993    @Override
6994    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6995        synchronized (this) {
6996            ProcessRecord app =
6997                who != null ? getRecordForAppLocked(who) : null;
6998            if (app == null) return;
6999
7000            Message msg = Message.obtain();
7001            msg.what = WAIT_FOR_DEBUGGER_MSG;
7002            msg.obj = app;
7003            msg.arg1 = waiting ? 1 : 0;
7004            mHandler.sendMessage(msg);
7005        }
7006    }
7007
7008    @Override
7009    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7010        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7011        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7012        outInfo.availMem = Process.getFreeMemory();
7013        outInfo.totalMem = Process.getTotalMemory();
7014        outInfo.threshold = homeAppMem;
7015        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7016        outInfo.hiddenAppThreshold = cachedAppMem;
7017        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7018                ProcessList.SERVICE_ADJ);
7019        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7020                ProcessList.VISIBLE_APP_ADJ);
7021        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7022                ProcessList.FOREGROUND_APP_ADJ);
7023    }
7024
7025    // =========================================================
7026    // TASK MANAGEMENT
7027    // =========================================================
7028
7029    @Override
7030    public List<IAppTask> getAppTasks() {
7031        int callingUid = Binder.getCallingUid();
7032        long ident = Binder.clearCallingIdentity();
7033        synchronized(this) {
7034            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7035            try {
7036                if (localLOGV) Slog.v(TAG, "getAppTasks");
7037
7038                final int N = mRecentTasks.size();
7039                for (int i = 0; i < N; i++) {
7040                    TaskRecord tr = mRecentTasks.get(i);
7041                    // Skip tasks that are not created by the caller
7042                    if (tr.creatorUid == callingUid) {
7043                        ActivityManager.RecentTaskInfo taskInfo =
7044                                createRecentTaskInfoFromTaskRecord(tr);
7045                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7046                        list.add(taskImpl);
7047                    }
7048                }
7049            } finally {
7050                Binder.restoreCallingIdentity(ident);
7051            }
7052            return list;
7053        }
7054    }
7055
7056    @Override
7057    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7058        final int callingUid = Binder.getCallingUid();
7059        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7060
7061        synchronized(this) {
7062            if (localLOGV) Slog.v(
7063                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7064
7065            final boolean allowed = checkCallingPermission(
7066                    android.Manifest.permission.GET_TASKS)
7067                    == PackageManager.PERMISSION_GRANTED;
7068            if (!allowed) {
7069                Slog.w(TAG, "getTasks: caller " + callingUid
7070                        + " does not hold GET_TASKS; limiting output");
7071            }
7072
7073            // TODO: Improve with MRU list from all ActivityStacks.
7074            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7075        }
7076
7077        return list;
7078    }
7079
7080    TaskRecord getMostRecentTask() {
7081        return mRecentTasks.get(0);
7082    }
7083
7084    /**
7085     * Creates a new RecentTaskInfo from a TaskRecord.
7086     */
7087    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7088        ActivityManager.RecentTaskInfo rti
7089                = new ActivityManager.RecentTaskInfo();
7090        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7091        rti.persistentId = tr.taskId;
7092        rti.baseIntent = new Intent(tr.getBaseIntent());
7093        rti.origActivity = tr.origActivity;
7094        rti.description = tr.lastDescription;
7095        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7096        rti.userId = tr.userId;
7097        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7098        return rti;
7099    }
7100
7101    @Override
7102    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7103            int flags, int userId) {
7104        final int callingUid = Binder.getCallingUid();
7105        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7106                false, true, "getRecentTasks", null);
7107
7108        synchronized (this) {
7109            final boolean allowed = checkCallingPermission(
7110                    android.Manifest.permission.GET_TASKS)
7111                    == PackageManager.PERMISSION_GRANTED;
7112            if (!allowed) {
7113                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7114                        + " does not hold GET_TASKS; limiting output");
7115            }
7116            final boolean detailed = checkCallingPermission(
7117                    android.Manifest.permission.GET_DETAILED_TASKS)
7118                    == PackageManager.PERMISSION_GRANTED;
7119
7120            IPackageManager pm = AppGlobals.getPackageManager();
7121
7122            final int N = mRecentTasks.size();
7123            ArrayList<ActivityManager.RecentTaskInfo> res
7124                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7125                            maxNum < N ? maxNum : N);
7126
7127            final Set<Integer> includedUsers;
7128            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7129                includedUsers = getProfileIdsLocked(userId);
7130            } else {
7131                includedUsers = new HashSet<Integer>();
7132            }
7133            includedUsers.add(Integer.valueOf(userId));
7134            for (int i=0; i<N && maxNum > 0; i++) {
7135                TaskRecord tr = mRecentTasks.get(i);
7136                // Only add calling user or related users recent tasks
7137                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7138
7139                // Return the entry if desired by the caller.  We always return
7140                // the first entry, because callers always expect this to be the
7141                // foreground app.  We may filter others if the caller has
7142                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7143                // we should exclude the entry.
7144
7145                if (i == 0
7146                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7147                        || (tr.intent == null)
7148                        || ((tr.intent.getFlags()
7149                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7150                    if (!allowed) {
7151                        // If the caller doesn't have the GET_TASKS permission, then only
7152                        // allow them to see a small subset of tasks -- their own and home.
7153                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7154                            continue;
7155                        }
7156                    }
7157
7158                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7159                    if (!detailed) {
7160                        rti.baseIntent.replaceExtras((Bundle)null);
7161                    }
7162
7163                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7164                        // Check whether this activity is currently available.
7165                        try {
7166                            if (rti.origActivity != null) {
7167                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7168                                        == null) {
7169                                    continue;
7170                                }
7171                            } else if (rti.baseIntent != null) {
7172                                if (pm.queryIntentActivities(rti.baseIntent,
7173                                        null, 0, userId) == null) {
7174                                    continue;
7175                                }
7176                            }
7177                        } catch (RemoteException e) {
7178                            // Will never happen.
7179                        }
7180                    }
7181
7182                    res.add(rti);
7183                    maxNum--;
7184                }
7185            }
7186            return res;
7187        }
7188    }
7189
7190    private TaskRecord recentTaskForIdLocked(int id) {
7191        final int N = mRecentTasks.size();
7192            for (int i=0; i<N; i++) {
7193                TaskRecord tr = mRecentTasks.get(i);
7194                if (tr.taskId == id) {
7195                    return tr;
7196                }
7197            }
7198            return null;
7199    }
7200
7201    @Override
7202    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7203        synchronized (this) {
7204            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7205                    "getTaskThumbnails()");
7206            TaskRecord tr = recentTaskForIdLocked(id);
7207            if (tr != null) {
7208                return tr.getTaskThumbnailsLocked();
7209            }
7210        }
7211        return null;
7212    }
7213
7214    @Override
7215    public Bitmap getTaskTopThumbnail(int id) {
7216        synchronized (this) {
7217            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7218                    "getTaskTopThumbnail()");
7219            TaskRecord tr = recentTaskForIdLocked(id);
7220            if (tr != null) {
7221                return tr.getTaskTopThumbnailLocked();
7222            }
7223        }
7224        return null;
7225    }
7226
7227    @Override
7228    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7229        synchronized (this) {
7230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7231            if (r != null) {
7232                r.taskDescription = td;
7233                r.task.updateTaskDescription();
7234            }
7235        }
7236    }
7237
7238    @Override
7239    public boolean removeSubTask(int taskId, int subTaskIndex) {
7240        synchronized (this) {
7241            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7242                    "removeSubTask()");
7243            long ident = Binder.clearCallingIdentity();
7244            try {
7245                TaskRecord tr = recentTaskForIdLocked(taskId);
7246                if (tr != null) {
7247                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7248                }
7249                return false;
7250            } finally {
7251                Binder.restoreCallingIdentity(ident);
7252            }
7253        }
7254    }
7255
7256    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7257        if (!pr.killedByAm) {
7258            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7259            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7260                    pr.processName, pr.setAdj, reason);
7261            pr.killedByAm = true;
7262            Process.killProcessQuiet(pr.pid);
7263        }
7264    }
7265
7266    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7267        tr.disposeThumbnail();
7268        mRecentTasks.remove(tr);
7269        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7270        Intent baseIntent = new Intent(
7271                tr.intent != null ? tr.intent : tr.affinityIntent);
7272        ComponentName component = baseIntent.getComponent();
7273        if (component == null) {
7274            Slog.w(TAG, "Now component for base intent of task: " + tr);
7275            return;
7276        }
7277
7278        // Find any running services associated with this app.
7279        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7280
7281        if (killProcesses) {
7282            // Find any running processes associated with this app.
7283            final String pkg = component.getPackageName();
7284            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7285            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7286            for (int i=0; i<pmap.size(); i++) {
7287                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7288                for (int j=0; j<uids.size(); j++) {
7289                    ProcessRecord proc = uids.valueAt(j);
7290                    if (proc.userId != tr.userId) {
7291                        continue;
7292                    }
7293                    if (!proc.pkgList.containsKey(pkg)) {
7294                        continue;
7295                    }
7296                    procs.add(proc);
7297                }
7298            }
7299
7300            // Kill the running processes.
7301            for (int i=0; i<procs.size(); i++) {
7302                ProcessRecord pr = procs.get(i);
7303                if (pr == mHomeProcess) {
7304                    // Don't kill the home process along with tasks from the same package.
7305                    continue;
7306                }
7307                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7308                    killUnneededProcessLocked(pr, "remove task");
7309                } else {
7310                    pr.waitingToKill = "remove task";
7311                }
7312            }
7313        }
7314    }
7315
7316    /**
7317     * Removes the task with the specified task id.
7318     *
7319     * @param taskId Identifier of the task to be removed.
7320     * @param flags Additional operational flags.  May be 0 or
7321     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7322     * @return Returns true if the given task was found and removed.
7323     */
7324    private boolean removeTaskByIdLocked(int taskId, int flags) {
7325        TaskRecord tr = recentTaskForIdLocked(taskId);
7326        if (tr != null) {
7327            tr.removeTaskActivitiesLocked(-1, false);
7328            cleanUpRemovedTaskLocked(tr, flags);
7329            if (tr.isPersistable) {
7330                notifyTaskPersisterLocked(tr, true);
7331            }
7332            return true;
7333        }
7334        return false;
7335    }
7336
7337    @Override
7338    public boolean removeTask(int taskId, int flags) {
7339        synchronized (this) {
7340            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7341                    "removeTask()");
7342            long ident = Binder.clearCallingIdentity();
7343            try {
7344                return removeTaskByIdLocked(taskId, flags);
7345            } finally {
7346                Binder.restoreCallingIdentity(ident);
7347            }
7348        }
7349    }
7350
7351    /**
7352     * TODO: Add mController hook
7353     */
7354    @Override
7355    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7356        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7357                "moveTaskToFront()");
7358
7359        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7360        synchronized(this) {
7361            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7362                    Binder.getCallingUid(), "Task to front")) {
7363                ActivityOptions.abort(options);
7364                return;
7365            }
7366            final long origId = Binder.clearCallingIdentity();
7367            try {
7368                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7369                if (task == null) {
7370                    return;
7371                }
7372                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7373                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7374                    return;
7375                }
7376                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7377            } finally {
7378                Binder.restoreCallingIdentity(origId);
7379            }
7380            ActivityOptions.abort(options);
7381        }
7382    }
7383
7384    @Override
7385    public void moveTaskToBack(int taskId) {
7386        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7387                "moveTaskToBack()");
7388
7389        synchronized(this) {
7390            TaskRecord tr = recentTaskForIdLocked(taskId);
7391            if (tr != null) {
7392                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7393                ActivityStack stack = tr.stack;
7394                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7395                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7396                            Binder.getCallingUid(), "Task to back")) {
7397                        return;
7398                    }
7399                }
7400                final long origId = Binder.clearCallingIdentity();
7401                try {
7402                    stack.moveTaskToBackLocked(taskId, null);
7403                } finally {
7404                    Binder.restoreCallingIdentity(origId);
7405                }
7406            }
7407        }
7408    }
7409
7410    /**
7411     * Moves an activity, and all of the other activities within the same task, to the bottom
7412     * of the history stack.  The activity's order within the task is unchanged.
7413     *
7414     * @param token A reference to the activity we wish to move
7415     * @param nonRoot If false then this only works if the activity is the root
7416     *                of a task; if true it will work for any activity in a task.
7417     * @return Returns true if the move completed, false if not.
7418     */
7419    @Override
7420    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7421        enforceNotIsolatedCaller("moveActivityTaskToBack");
7422        synchronized(this) {
7423            final long origId = Binder.clearCallingIdentity();
7424            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7425            if (taskId >= 0) {
7426                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7427            }
7428            Binder.restoreCallingIdentity(origId);
7429        }
7430        return false;
7431    }
7432
7433    @Override
7434    public void moveTaskBackwards(int task) {
7435        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7436                "moveTaskBackwards()");
7437
7438        synchronized(this) {
7439            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7440                    Binder.getCallingUid(), "Task backwards")) {
7441                return;
7442            }
7443            final long origId = Binder.clearCallingIdentity();
7444            moveTaskBackwardsLocked(task);
7445            Binder.restoreCallingIdentity(origId);
7446        }
7447    }
7448
7449    private final void moveTaskBackwardsLocked(int task) {
7450        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7451    }
7452
7453    @Override
7454    public IBinder getHomeActivityToken() throws RemoteException {
7455        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7456                "getHomeActivityToken()");
7457        synchronized (this) {
7458            return mStackSupervisor.getHomeActivityToken();
7459        }
7460    }
7461
7462    @Override
7463    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7464            IActivityContainerCallback callback) throws RemoteException {
7465        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7466                "createActivityContainer()");
7467        synchronized (this) {
7468            if (parentActivityToken == null) {
7469                throw new IllegalArgumentException("parent token must not be null");
7470            }
7471            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7472            if (r == null) {
7473                return null;
7474            }
7475            if (callback == null) {
7476                throw new IllegalArgumentException("callback must not be null");
7477            }
7478            return mStackSupervisor.createActivityContainer(r, callback);
7479        }
7480    }
7481
7482    @Override
7483    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7484        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7485                "deleteActivityContainer()");
7486        synchronized (this) {
7487            mStackSupervisor.deleteActivityContainer(container);
7488        }
7489    }
7490
7491    @Override
7492    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7493            throws RemoteException {
7494        synchronized (this) {
7495            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7496            if (stack != null) {
7497                return stack.mActivityContainer;
7498            }
7499            return null;
7500        }
7501    }
7502
7503    @Override
7504    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7505        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7506                "moveTaskToStack()");
7507        if (stackId == HOME_STACK_ID) {
7508            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7509                    new RuntimeException("here").fillInStackTrace());
7510        }
7511        synchronized (this) {
7512            long ident = Binder.clearCallingIdentity();
7513            try {
7514                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7515                        + stackId + " toTop=" + toTop);
7516                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7517            } finally {
7518                Binder.restoreCallingIdentity(ident);
7519            }
7520        }
7521    }
7522
7523    @Override
7524    public void resizeStack(int stackBoxId, Rect bounds) {
7525        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7526                "resizeStackBox()");
7527        long ident = Binder.clearCallingIdentity();
7528        try {
7529            mWindowManager.resizeStack(stackBoxId, bounds);
7530        } finally {
7531            Binder.restoreCallingIdentity(ident);
7532        }
7533    }
7534
7535    @Override
7536    public List<StackInfo> getAllStackInfos() {
7537        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7538                "getAllStackInfos()");
7539        long ident = Binder.clearCallingIdentity();
7540        try {
7541            synchronized (this) {
7542                return mStackSupervisor.getAllStackInfosLocked();
7543            }
7544        } finally {
7545            Binder.restoreCallingIdentity(ident);
7546        }
7547    }
7548
7549    @Override
7550    public StackInfo getStackInfo(int stackId) {
7551        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7552                "getStackInfo()");
7553        long ident = Binder.clearCallingIdentity();
7554        try {
7555            synchronized (this) {
7556                return mStackSupervisor.getStackInfoLocked(stackId);
7557            }
7558        } finally {
7559            Binder.restoreCallingIdentity(ident);
7560        }
7561    }
7562
7563    @Override
7564    public boolean isInHomeStack(int taskId) {
7565        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7566                "getStackInfo()");
7567        long ident = Binder.clearCallingIdentity();
7568        try {
7569            synchronized (this) {
7570                TaskRecord tr = recentTaskForIdLocked(taskId);
7571                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7572            }
7573        } finally {
7574            Binder.restoreCallingIdentity(ident);
7575        }
7576    }
7577
7578    @Override
7579    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7580        synchronized(this) {
7581            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7582        }
7583    }
7584
7585    private boolean isLockTaskAuthorized(ComponentName name) {
7586        final DevicePolicyManager dpm = (DevicePolicyManager)
7587                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7588        return dpm != null && dpm.isLockTaskPermitted(name);
7589    }
7590
7591    private void startLockTaskMode(TaskRecord task) {
7592        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7593            return;
7594        }
7595        long ident = Binder.clearCallingIdentity();
7596        try {
7597            synchronized (this) {
7598                // Since we lost lock on task, make sure it is still there.
7599                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7600                if (task != null) {
7601                    mStackSupervisor.setLockTaskModeLocked(task);
7602                }
7603            }
7604        } finally {
7605            Binder.restoreCallingIdentity(ident);
7606        }
7607    }
7608
7609    @Override
7610    public void startLockTaskMode(int taskId) {
7611        long ident = Binder.clearCallingIdentity();
7612        try {
7613            final TaskRecord task;
7614            synchronized (this) {
7615                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7616            }
7617            if (task != null) {
7618                startLockTaskMode(task);
7619            }
7620        } finally {
7621            Binder.restoreCallingIdentity(ident);
7622        }
7623    }
7624
7625    @Override
7626    public void startLockTaskMode(IBinder token) {
7627        long ident = Binder.clearCallingIdentity();
7628        try {
7629            final TaskRecord task;
7630            synchronized (this) {
7631                final ActivityRecord r = ActivityRecord.forToken(token);
7632                if (r == null) {
7633                    return;
7634                }
7635                task = r.task;
7636            }
7637            if (task != null) {
7638                startLockTaskMode(task);
7639            }
7640        } finally {
7641            Binder.restoreCallingIdentity(ident);
7642        }
7643    }
7644
7645    @Override
7646    public void stopLockTaskMode() {
7647        // Check if the calling task is eligible to use lock task
7648        final int uid = Binder.getCallingUid();
7649        try {
7650            final String name = AppGlobals.getPackageManager().getNameForUid(uid);
7651            if (!isLockTaskAuthorized(new ComponentName(name, name))) {
7652                return;
7653            }
7654        } catch (RemoteException e) {
7655            Log.d(TAG, "stopLockTaskMode " + e);
7656            return;
7657        }
7658        // Stop lock task
7659        synchronized (this) {
7660            mStackSupervisor.setLockTaskModeLocked(null);
7661        }
7662    }
7663
7664    @Override
7665    public boolean isInLockTaskMode() {
7666        synchronized (this) {
7667            return mStackSupervisor.isInLockTaskMode();
7668        }
7669    }
7670
7671    // =========================================================
7672    // CONTENT PROVIDERS
7673    // =========================================================
7674
7675    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7676        List<ProviderInfo> providers = null;
7677        try {
7678            providers = AppGlobals.getPackageManager().
7679                queryContentProviders(app.processName, app.uid,
7680                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7681        } catch (RemoteException ex) {
7682        }
7683        if (DEBUG_MU)
7684            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7685        int userId = app.userId;
7686        if (providers != null) {
7687            int N = providers.size();
7688            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7689            for (int i=0; i<N; i++) {
7690                ProviderInfo cpi =
7691                    (ProviderInfo)providers.get(i);
7692                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7693                        cpi.name, cpi.flags);
7694                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7695                    // This is a singleton provider, but a user besides the
7696                    // default user is asking to initialize a process it runs
7697                    // in...  well, no, it doesn't actually run in this process,
7698                    // it runs in the process of the default user.  Get rid of it.
7699                    providers.remove(i);
7700                    N--;
7701                    i--;
7702                    continue;
7703                }
7704
7705                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7706                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7707                if (cpr == null) {
7708                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7709                    mProviderMap.putProviderByClass(comp, cpr);
7710                }
7711                if (DEBUG_MU)
7712                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7713                app.pubProviders.put(cpi.name, cpr);
7714                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7715                    // Don't add this if it is a platform component that is marked
7716                    // to run in multiple processes, because this is actually
7717                    // part of the framework so doesn't make sense to track as a
7718                    // separate apk in the process.
7719                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7720                }
7721                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7722            }
7723        }
7724        return providers;
7725    }
7726
7727    /**
7728     * Check if {@link ProcessRecord} has a possible chance at accessing the
7729     * given {@link ProviderInfo}. Final permission checking is always done
7730     * in {@link ContentProvider}.
7731     */
7732    private final String checkContentProviderPermissionLocked(
7733            ProviderInfo cpi, ProcessRecord r, int userId) {
7734        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7735        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7736        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7737        // Looking for cross-user grants before to enforce the typical cross-users permissions
7738        if (userId != UserHandle.getUserId(callingUid)) {
7739            if (perms != null) {
7740                for (GrantUri grantUri : perms.keySet()) {
7741                    if (grantUri.sourceUserId == userId) {
7742                        String authority = grantUri.uri.getAuthority();
7743                        if (authority.equals(cpi.authority)) {
7744                            return null;
7745                        }
7746                    }
7747                }
7748            }
7749        }
7750        userId = handleIncomingUser(callingPid, callingUid, userId,
7751                false, true, "checkContentProviderPermissionLocked", null);
7752        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7753                cpi.applicationInfo.uid, cpi.exported)
7754                == PackageManager.PERMISSION_GRANTED) {
7755            return null;
7756        }
7757        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7758                cpi.applicationInfo.uid, cpi.exported)
7759                == PackageManager.PERMISSION_GRANTED) {
7760            return null;
7761        }
7762
7763        PathPermission[] pps = cpi.pathPermissions;
7764        if (pps != null) {
7765            int i = pps.length;
7766            while (i > 0) {
7767                i--;
7768                PathPermission pp = pps[i];
7769                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7770                        cpi.applicationInfo.uid, cpi.exported)
7771                        == PackageManager.PERMISSION_GRANTED) {
7772                    return null;
7773                }
7774                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7775                        cpi.applicationInfo.uid, cpi.exported)
7776                        == PackageManager.PERMISSION_GRANTED) {
7777                    return null;
7778                }
7779            }
7780        }
7781
7782        if (perms != null) {
7783            for (GrantUri grantUri : perms.keySet()) {
7784                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7785                    return null;
7786                }
7787            }
7788        }
7789
7790        String msg;
7791        if (!cpi.exported) {
7792            msg = "Permission Denial: opening provider " + cpi.name
7793                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7794                    + ", uid=" + callingUid + ") that is not exported from uid "
7795                    + cpi.applicationInfo.uid;
7796        } else {
7797            msg = "Permission Denial: opening provider " + cpi.name
7798                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7799                    + ", uid=" + callingUid + ") requires "
7800                    + cpi.readPermission + " or " + cpi.writePermission;
7801        }
7802        Slog.w(TAG, msg);
7803        return msg;
7804    }
7805
7806    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7807            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7808        if (r != null) {
7809            for (int i=0; i<r.conProviders.size(); i++) {
7810                ContentProviderConnection conn = r.conProviders.get(i);
7811                if (conn.provider == cpr) {
7812                    if (DEBUG_PROVIDER) Slog.v(TAG,
7813                            "Adding provider requested by "
7814                            + r.processName + " from process "
7815                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7816                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7817                    if (stable) {
7818                        conn.stableCount++;
7819                        conn.numStableIncs++;
7820                    } else {
7821                        conn.unstableCount++;
7822                        conn.numUnstableIncs++;
7823                    }
7824                    return conn;
7825                }
7826            }
7827            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7828            if (stable) {
7829                conn.stableCount = 1;
7830                conn.numStableIncs = 1;
7831            } else {
7832                conn.unstableCount = 1;
7833                conn.numUnstableIncs = 1;
7834            }
7835            cpr.connections.add(conn);
7836            r.conProviders.add(conn);
7837            return conn;
7838        }
7839        cpr.addExternalProcessHandleLocked(externalProcessToken);
7840        return null;
7841    }
7842
7843    boolean decProviderCountLocked(ContentProviderConnection conn,
7844            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7845        if (conn != null) {
7846            cpr = conn.provider;
7847            if (DEBUG_PROVIDER) Slog.v(TAG,
7848                    "Removing provider requested by "
7849                    + conn.client.processName + " from process "
7850                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7851                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7852            if (stable) {
7853                conn.stableCount--;
7854            } else {
7855                conn.unstableCount--;
7856            }
7857            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7858                cpr.connections.remove(conn);
7859                conn.client.conProviders.remove(conn);
7860                return true;
7861            }
7862            return false;
7863        }
7864        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7865        return false;
7866    }
7867
7868    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7869            String name, IBinder token, boolean stable, int userId) {
7870        ContentProviderRecord cpr;
7871        ContentProviderConnection conn = null;
7872        ProviderInfo cpi = null;
7873
7874        synchronized(this) {
7875            ProcessRecord r = null;
7876            if (caller != null) {
7877                r = getRecordForAppLocked(caller);
7878                if (r == null) {
7879                    throw new SecurityException(
7880                            "Unable to find app for caller " + caller
7881                          + " (pid=" + Binder.getCallingPid()
7882                          + ") when getting content provider " + name);
7883                }
7884            }
7885
7886            // First check if this content provider has been published...
7887            cpr = mProviderMap.getProviderByName(name, userId);
7888            boolean providerRunning = cpr != null;
7889            if (providerRunning) {
7890                cpi = cpr.info;
7891                String msg;
7892                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7893                    throw new SecurityException(msg);
7894                }
7895
7896                if (r != null && cpr.canRunHere(r)) {
7897                    // This provider has been published or is in the process
7898                    // of being published...  but it is also allowed to run
7899                    // in the caller's process, so don't make a connection
7900                    // and just let the caller instantiate its own instance.
7901                    ContentProviderHolder holder = cpr.newHolder(null);
7902                    // don't give caller the provider object, it needs
7903                    // to make its own.
7904                    holder.provider = null;
7905                    return holder;
7906                }
7907
7908                final long origId = Binder.clearCallingIdentity();
7909
7910                // In this case the provider instance already exists, so we can
7911                // return it right away.
7912                conn = incProviderCountLocked(r, cpr, token, stable);
7913                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7914                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7915                        // If this is a perceptible app accessing the provider,
7916                        // make sure to count it as being accessed and thus
7917                        // back up on the LRU list.  This is good because
7918                        // content providers are often expensive to start.
7919                        updateLruProcessLocked(cpr.proc, false, null);
7920                    }
7921                }
7922
7923                if (cpr.proc != null) {
7924                    if (false) {
7925                        if (cpr.name.flattenToShortString().equals(
7926                                "com.android.providers.calendar/.CalendarProvider2")) {
7927                            Slog.v(TAG, "****************** KILLING "
7928                                + cpr.name.flattenToShortString());
7929                            Process.killProcess(cpr.proc.pid);
7930                        }
7931                    }
7932                    boolean success = updateOomAdjLocked(cpr.proc);
7933                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7934                    // NOTE: there is still a race here where a signal could be
7935                    // pending on the process even though we managed to update its
7936                    // adj level.  Not sure what to do about this, but at least
7937                    // the race is now smaller.
7938                    if (!success) {
7939                        // Uh oh...  it looks like the provider's process
7940                        // has been killed on us.  We need to wait for a new
7941                        // process to be started, and make sure its death
7942                        // doesn't kill our process.
7943                        Slog.i(TAG,
7944                                "Existing provider " + cpr.name.flattenToShortString()
7945                                + " is crashing; detaching " + r);
7946                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7947                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7948                        if (!lastRef) {
7949                            // This wasn't the last ref our process had on
7950                            // the provider...  we have now been killed, bail.
7951                            return null;
7952                        }
7953                        providerRunning = false;
7954                        conn = null;
7955                    }
7956                }
7957
7958                Binder.restoreCallingIdentity(origId);
7959            }
7960
7961            boolean singleton;
7962            if (!providerRunning) {
7963                try {
7964                    cpi = AppGlobals.getPackageManager().
7965                        resolveContentProvider(name,
7966                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7967                } catch (RemoteException ex) {
7968                }
7969                if (cpi == null) {
7970                    return null;
7971                }
7972                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7973                        cpi.name, cpi.flags);
7974                if (singleton) {
7975                    userId = 0;
7976                }
7977                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7978
7979                String msg;
7980                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7981                    throw new SecurityException(msg);
7982                }
7983
7984                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7985                        && !cpi.processName.equals("system")) {
7986                    // If this content provider does not run in the system
7987                    // process, and the system is not yet ready to run other
7988                    // processes, then fail fast instead of hanging.
7989                    throw new IllegalArgumentException(
7990                            "Attempt to launch content provider before system ready");
7991                }
7992
7993                // Make sure that the user who owns this provider is started.  If not,
7994                // we don't want to allow it to run.
7995                if (mStartedUsers.get(userId) == null) {
7996                    Slog.w(TAG, "Unable to launch app "
7997                            + cpi.applicationInfo.packageName + "/"
7998                            + cpi.applicationInfo.uid + " for provider "
7999                            + name + ": user " + userId + " is stopped");
8000                    return null;
8001                }
8002
8003                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8004                cpr = mProviderMap.getProviderByClass(comp, userId);
8005                final boolean firstClass = cpr == null;
8006                if (firstClass) {
8007                    try {
8008                        ApplicationInfo ai =
8009                            AppGlobals.getPackageManager().
8010                                getApplicationInfo(
8011                                        cpi.applicationInfo.packageName,
8012                                        STOCK_PM_FLAGS, userId);
8013                        if (ai == null) {
8014                            Slog.w(TAG, "No package info for content provider "
8015                                    + cpi.name);
8016                            return null;
8017                        }
8018                        ai = getAppInfoForUser(ai, userId);
8019                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8020                    } catch (RemoteException ex) {
8021                        // pm is in same process, this will never happen.
8022                    }
8023                }
8024
8025                if (r != null && cpr.canRunHere(r)) {
8026                    // If this is a multiprocess provider, then just return its
8027                    // info and allow the caller to instantiate it.  Only do
8028                    // this if the provider is the same user as the caller's
8029                    // process, or can run as root (so can be in any process).
8030                    return cpr.newHolder(null);
8031                }
8032
8033                if (DEBUG_PROVIDER) {
8034                    RuntimeException e = new RuntimeException("here");
8035                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8036                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8037                }
8038
8039                // This is single process, and our app is now connecting to it.
8040                // See if we are already in the process of launching this
8041                // provider.
8042                final int N = mLaunchingProviders.size();
8043                int i;
8044                for (i=0; i<N; i++) {
8045                    if (mLaunchingProviders.get(i) == cpr) {
8046                        break;
8047                    }
8048                }
8049
8050                // If the provider is not already being launched, then get it
8051                // started.
8052                if (i >= N) {
8053                    final long origId = Binder.clearCallingIdentity();
8054
8055                    try {
8056                        // Content provider is now in use, its package can't be stopped.
8057                        try {
8058                            AppGlobals.getPackageManager().setPackageStoppedState(
8059                                    cpr.appInfo.packageName, false, userId);
8060                        } catch (RemoteException e) {
8061                        } catch (IllegalArgumentException e) {
8062                            Slog.w(TAG, "Failed trying to unstop package "
8063                                    + cpr.appInfo.packageName + ": " + e);
8064                        }
8065
8066                        // Use existing process if already started
8067                        ProcessRecord proc = getProcessRecordLocked(
8068                                cpi.processName, cpr.appInfo.uid, false);
8069                        if (proc != null && proc.thread != null) {
8070                            if (DEBUG_PROVIDER) {
8071                                Slog.d(TAG, "Installing in existing process " + proc);
8072                            }
8073                            proc.pubProviders.put(cpi.name, cpr);
8074                            try {
8075                                proc.thread.scheduleInstallProvider(cpi);
8076                            } catch (RemoteException e) {
8077                            }
8078                        } else {
8079                            proc = startProcessLocked(cpi.processName,
8080                                    cpr.appInfo, false, 0, "content provider",
8081                                    new ComponentName(cpi.applicationInfo.packageName,
8082                                            cpi.name), false, false, false);
8083                            if (proc == null) {
8084                                Slog.w(TAG, "Unable to launch app "
8085                                        + cpi.applicationInfo.packageName + "/"
8086                                        + cpi.applicationInfo.uid + " for provider "
8087                                        + name + ": process is bad");
8088                                return null;
8089                            }
8090                        }
8091                        cpr.launchingApp = proc;
8092                        mLaunchingProviders.add(cpr);
8093                    } finally {
8094                        Binder.restoreCallingIdentity(origId);
8095                    }
8096                }
8097
8098                // Make sure the provider is published (the same provider class
8099                // may be published under multiple names).
8100                if (firstClass) {
8101                    mProviderMap.putProviderByClass(comp, cpr);
8102                }
8103
8104                mProviderMap.putProviderByName(name, cpr);
8105                conn = incProviderCountLocked(r, cpr, token, stable);
8106                if (conn != null) {
8107                    conn.waiting = true;
8108                }
8109            }
8110        }
8111
8112        // Wait for the provider to be published...
8113        synchronized (cpr) {
8114            while (cpr.provider == null) {
8115                if (cpr.launchingApp == null) {
8116                    Slog.w(TAG, "Unable to launch app "
8117                            + cpi.applicationInfo.packageName + "/"
8118                            + cpi.applicationInfo.uid + " for provider "
8119                            + name + ": launching app became null");
8120                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8121                            UserHandle.getUserId(cpi.applicationInfo.uid),
8122                            cpi.applicationInfo.packageName,
8123                            cpi.applicationInfo.uid, name);
8124                    return null;
8125                }
8126                try {
8127                    if (DEBUG_MU) {
8128                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8129                                + cpr.launchingApp);
8130                    }
8131                    if (conn != null) {
8132                        conn.waiting = true;
8133                    }
8134                    cpr.wait();
8135                } catch (InterruptedException ex) {
8136                } finally {
8137                    if (conn != null) {
8138                        conn.waiting = false;
8139                    }
8140                }
8141            }
8142        }
8143        return cpr != null ? cpr.newHolder(conn) : null;
8144    }
8145
8146    @Override
8147    public final ContentProviderHolder getContentProvider(
8148            IApplicationThread caller, String name, int userId, boolean stable) {
8149        enforceNotIsolatedCaller("getContentProvider");
8150        if (caller == null) {
8151            String msg = "null IApplicationThread when getting content provider "
8152                    + name;
8153            Slog.w(TAG, msg);
8154            throw new SecurityException(msg);
8155        }
8156        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8157        // with cross-user grant.
8158        return getContentProviderImpl(caller, name, null, stable, userId);
8159    }
8160
8161    public ContentProviderHolder getContentProviderExternal(
8162            String name, int userId, IBinder token) {
8163        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8164            "Do not have permission in call getContentProviderExternal()");
8165        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8166                false, true, "getContentProvider", null);
8167        return getContentProviderExternalUnchecked(name, token, userId);
8168    }
8169
8170    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8171            IBinder token, int userId) {
8172        return getContentProviderImpl(null, name, token, true, userId);
8173    }
8174
8175    /**
8176     * Drop a content provider from a ProcessRecord's bookkeeping
8177     */
8178    public void removeContentProvider(IBinder connection, boolean stable) {
8179        enforceNotIsolatedCaller("removeContentProvider");
8180        long ident = Binder.clearCallingIdentity();
8181        try {
8182            synchronized (this) {
8183                ContentProviderConnection conn;
8184                try {
8185                    conn = (ContentProviderConnection)connection;
8186                } catch (ClassCastException e) {
8187                    String msg ="removeContentProvider: " + connection
8188                            + " not a ContentProviderConnection";
8189                    Slog.w(TAG, msg);
8190                    throw new IllegalArgumentException(msg);
8191                }
8192                if (conn == null) {
8193                    throw new NullPointerException("connection is null");
8194                }
8195                if (decProviderCountLocked(conn, null, null, stable)) {
8196                    updateOomAdjLocked();
8197                }
8198            }
8199        } finally {
8200            Binder.restoreCallingIdentity(ident);
8201        }
8202    }
8203
8204    public void removeContentProviderExternal(String name, IBinder token) {
8205        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8206            "Do not have permission in call removeContentProviderExternal()");
8207        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8208    }
8209
8210    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8211        synchronized (this) {
8212            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8213            if(cpr == null) {
8214                //remove from mProvidersByClass
8215                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8216                return;
8217            }
8218
8219            //update content provider record entry info
8220            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8221            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8222            if (localCpr.hasExternalProcessHandles()) {
8223                if (localCpr.removeExternalProcessHandleLocked(token)) {
8224                    updateOomAdjLocked();
8225                } else {
8226                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8227                            + " with no external reference for token: "
8228                            + token + ".");
8229                }
8230            } else {
8231                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8232                        + " with no external references.");
8233            }
8234        }
8235    }
8236
8237    public final void publishContentProviders(IApplicationThread caller,
8238            List<ContentProviderHolder> providers) {
8239        if (providers == null) {
8240            return;
8241        }
8242
8243        enforceNotIsolatedCaller("publishContentProviders");
8244        synchronized (this) {
8245            final ProcessRecord r = getRecordForAppLocked(caller);
8246            if (DEBUG_MU)
8247                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8248            if (r == null) {
8249                throw new SecurityException(
8250                        "Unable to find app for caller " + caller
8251                      + " (pid=" + Binder.getCallingPid()
8252                      + ") when publishing content providers");
8253            }
8254
8255            final long origId = Binder.clearCallingIdentity();
8256
8257            final int N = providers.size();
8258            for (int i=0; i<N; i++) {
8259                ContentProviderHolder src = providers.get(i);
8260                if (src == null || src.info == null || src.provider == null) {
8261                    continue;
8262                }
8263                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8264                if (DEBUG_MU)
8265                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8266                if (dst != null) {
8267                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8268                    mProviderMap.putProviderByClass(comp, dst);
8269                    String names[] = dst.info.authority.split(";");
8270                    for (int j = 0; j < names.length; j++) {
8271                        mProviderMap.putProviderByName(names[j], dst);
8272                    }
8273
8274                    int NL = mLaunchingProviders.size();
8275                    int j;
8276                    for (j=0; j<NL; j++) {
8277                        if (mLaunchingProviders.get(j) == dst) {
8278                            mLaunchingProviders.remove(j);
8279                            j--;
8280                            NL--;
8281                        }
8282                    }
8283                    synchronized (dst) {
8284                        dst.provider = src.provider;
8285                        dst.proc = r;
8286                        dst.notifyAll();
8287                    }
8288                    updateOomAdjLocked(r);
8289                }
8290            }
8291
8292            Binder.restoreCallingIdentity(origId);
8293        }
8294    }
8295
8296    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8297        ContentProviderConnection conn;
8298        try {
8299            conn = (ContentProviderConnection)connection;
8300        } catch (ClassCastException e) {
8301            String msg ="refContentProvider: " + connection
8302                    + " not a ContentProviderConnection";
8303            Slog.w(TAG, msg);
8304            throw new IllegalArgumentException(msg);
8305        }
8306        if (conn == null) {
8307            throw new NullPointerException("connection is null");
8308        }
8309
8310        synchronized (this) {
8311            if (stable > 0) {
8312                conn.numStableIncs += stable;
8313            }
8314            stable = conn.stableCount + stable;
8315            if (stable < 0) {
8316                throw new IllegalStateException("stableCount < 0: " + stable);
8317            }
8318
8319            if (unstable > 0) {
8320                conn.numUnstableIncs += unstable;
8321            }
8322            unstable = conn.unstableCount + unstable;
8323            if (unstable < 0) {
8324                throw new IllegalStateException("unstableCount < 0: " + unstable);
8325            }
8326
8327            if ((stable+unstable) <= 0) {
8328                throw new IllegalStateException("ref counts can't go to zero here: stable="
8329                        + stable + " unstable=" + unstable);
8330            }
8331            conn.stableCount = stable;
8332            conn.unstableCount = unstable;
8333            return !conn.dead;
8334        }
8335    }
8336
8337    public void unstableProviderDied(IBinder connection) {
8338        ContentProviderConnection conn;
8339        try {
8340            conn = (ContentProviderConnection)connection;
8341        } catch (ClassCastException e) {
8342            String msg ="refContentProvider: " + connection
8343                    + " not a ContentProviderConnection";
8344            Slog.w(TAG, msg);
8345            throw new IllegalArgumentException(msg);
8346        }
8347        if (conn == null) {
8348            throw new NullPointerException("connection is null");
8349        }
8350
8351        // Safely retrieve the content provider associated with the connection.
8352        IContentProvider provider;
8353        synchronized (this) {
8354            provider = conn.provider.provider;
8355        }
8356
8357        if (provider == null) {
8358            // Um, yeah, we're way ahead of you.
8359            return;
8360        }
8361
8362        // Make sure the caller is being honest with us.
8363        if (provider.asBinder().pingBinder()) {
8364            // Er, no, still looks good to us.
8365            synchronized (this) {
8366                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8367                        + " says " + conn + " died, but we don't agree");
8368                return;
8369            }
8370        }
8371
8372        // Well look at that!  It's dead!
8373        synchronized (this) {
8374            if (conn.provider.provider != provider) {
8375                // But something changed...  good enough.
8376                return;
8377            }
8378
8379            ProcessRecord proc = conn.provider.proc;
8380            if (proc == null || proc.thread == null) {
8381                // Seems like the process is already cleaned up.
8382                return;
8383            }
8384
8385            // As far as we're concerned, this is just like receiving a
8386            // death notification...  just a bit prematurely.
8387            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8388                    + ") early provider death");
8389            final long ident = Binder.clearCallingIdentity();
8390            try {
8391                appDiedLocked(proc, proc.pid, proc.thread);
8392            } finally {
8393                Binder.restoreCallingIdentity(ident);
8394            }
8395        }
8396    }
8397
8398    @Override
8399    public void appNotRespondingViaProvider(IBinder connection) {
8400        enforceCallingPermission(
8401                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8402
8403        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8404        if (conn == null) {
8405            Slog.w(TAG, "ContentProviderConnection is null");
8406            return;
8407        }
8408
8409        final ProcessRecord host = conn.provider.proc;
8410        if (host == null) {
8411            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8412            return;
8413        }
8414
8415        final long token = Binder.clearCallingIdentity();
8416        try {
8417            appNotResponding(host, null, null, false, "ContentProvider not responding");
8418        } finally {
8419            Binder.restoreCallingIdentity(token);
8420        }
8421    }
8422
8423    public final void installSystemProviders() {
8424        List<ProviderInfo> providers;
8425        synchronized (this) {
8426            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8427            providers = generateApplicationProvidersLocked(app);
8428            if (providers != null) {
8429                for (int i=providers.size()-1; i>=0; i--) {
8430                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8431                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8432                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8433                                + ": not system .apk");
8434                        providers.remove(i);
8435                    }
8436                }
8437            }
8438        }
8439        if (providers != null) {
8440            mSystemThread.installSystemProviders(providers);
8441        }
8442
8443        mCoreSettingsObserver = new CoreSettingsObserver(this);
8444
8445        mUsageStatsService.monitorPackages();
8446    }
8447
8448    /**
8449     * Allows app to retrieve the MIME type of a URI without having permission
8450     * to access its content provider.
8451     *
8452     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8453     *
8454     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8455     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8456     */
8457    public String getProviderMimeType(Uri uri, int userId) {
8458        enforceNotIsolatedCaller("getProviderMimeType");
8459        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8460                userId, false, true, "getProviderMimeType", null);
8461        final String name = uri.getAuthority();
8462        final long ident = Binder.clearCallingIdentity();
8463        ContentProviderHolder holder = null;
8464
8465        try {
8466            holder = getContentProviderExternalUnchecked(name, null, userId);
8467            if (holder != null) {
8468                return holder.provider.getType(uri);
8469            }
8470        } catch (RemoteException e) {
8471            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8472            return null;
8473        } finally {
8474            if (holder != null) {
8475                removeContentProviderExternalUnchecked(name, null, userId);
8476            }
8477            Binder.restoreCallingIdentity(ident);
8478        }
8479
8480        return null;
8481    }
8482
8483    // =========================================================
8484    // GLOBAL MANAGEMENT
8485    // =========================================================
8486
8487    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8488            boolean isolated) {
8489        String proc = customProcess != null ? customProcess : info.processName;
8490        BatteryStatsImpl.Uid.Proc ps = null;
8491        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8492        int uid = info.uid;
8493        if (isolated) {
8494            int userId = UserHandle.getUserId(uid);
8495            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8496            while (true) {
8497                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8498                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8499                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8500                }
8501                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8502                mNextIsolatedProcessUid++;
8503                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8504                    // No process for this uid, use it.
8505                    break;
8506                }
8507                stepsLeft--;
8508                if (stepsLeft <= 0) {
8509                    return null;
8510                }
8511            }
8512        }
8513        return new ProcessRecord(stats, info, proc, uid);
8514    }
8515
8516    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8517        ProcessRecord app;
8518        if (!isolated) {
8519            app = getProcessRecordLocked(info.processName, info.uid, true);
8520        } else {
8521            app = null;
8522        }
8523
8524        if (app == null) {
8525            app = newProcessRecordLocked(info, null, isolated);
8526            mProcessNames.put(info.processName, app.uid, app);
8527            if (isolated) {
8528                mIsolatedProcesses.put(app.uid, app);
8529            }
8530            updateLruProcessLocked(app, false, null);
8531            updateOomAdjLocked();
8532        }
8533
8534        // This package really, really can not be stopped.
8535        try {
8536            AppGlobals.getPackageManager().setPackageStoppedState(
8537                    info.packageName, false, UserHandle.getUserId(app.uid));
8538        } catch (RemoteException e) {
8539        } catch (IllegalArgumentException e) {
8540            Slog.w(TAG, "Failed trying to unstop package "
8541                    + info.packageName + ": " + e);
8542        }
8543
8544        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8545                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8546            app.persistent = true;
8547            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8548        }
8549        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8550            mPersistentStartingProcesses.add(app);
8551            startProcessLocked(app, "added application", app.processName);
8552        }
8553
8554        return app;
8555    }
8556
8557    public void unhandledBack() {
8558        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8559                "unhandledBack()");
8560
8561        synchronized(this) {
8562            final long origId = Binder.clearCallingIdentity();
8563            try {
8564                getFocusedStack().unhandledBackLocked();
8565            } finally {
8566                Binder.restoreCallingIdentity(origId);
8567            }
8568        }
8569    }
8570
8571    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8572        enforceNotIsolatedCaller("openContentUri");
8573        final int userId = UserHandle.getCallingUserId();
8574        String name = uri.getAuthority();
8575        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8576        ParcelFileDescriptor pfd = null;
8577        if (cph != null) {
8578            // We record the binder invoker's uid in thread-local storage before
8579            // going to the content provider to open the file.  Later, in the code
8580            // that handles all permissions checks, we look for this uid and use
8581            // that rather than the Activity Manager's own uid.  The effect is that
8582            // we do the check against the caller's permissions even though it looks
8583            // to the content provider like the Activity Manager itself is making
8584            // the request.
8585            sCallerIdentity.set(new Identity(
8586                    Binder.getCallingPid(), Binder.getCallingUid()));
8587            try {
8588                pfd = cph.provider.openFile(null, uri, "r", null);
8589            } catch (FileNotFoundException e) {
8590                // do nothing; pfd will be returned null
8591            } finally {
8592                // Ensure that whatever happens, we clean up the identity state
8593                sCallerIdentity.remove();
8594            }
8595
8596            // We've got the fd now, so we're done with the provider.
8597            removeContentProviderExternalUnchecked(name, null, userId);
8598        } else {
8599            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8600        }
8601        return pfd;
8602    }
8603
8604    // Actually is sleeping or shutting down or whatever else in the future
8605    // is an inactive state.
8606    public boolean isSleepingOrShuttingDown() {
8607        return mSleeping || mShuttingDown;
8608    }
8609
8610    public boolean isSleeping() {
8611        return mSleeping;
8612    }
8613
8614    void goingToSleep() {
8615        synchronized(this) {
8616            mWentToSleep = true;
8617            updateEventDispatchingLocked();
8618            goToSleepIfNeededLocked();
8619        }
8620    }
8621
8622    void finishRunningVoiceLocked() {
8623        if (mRunningVoice) {
8624            mRunningVoice = false;
8625            goToSleepIfNeededLocked();
8626        }
8627    }
8628
8629    void goToSleepIfNeededLocked() {
8630        if (mWentToSleep && !mRunningVoice) {
8631            if (!mSleeping) {
8632                mSleeping = true;
8633                mStackSupervisor.goingToSleepLocked();
8634
8635                // Initialize the wake times of all processes.
8636                checkExcessivePowerUsageLocked(false);
8637                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8638                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8639                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8640            }
8641        }
8642    }
8643
8644    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8645        mTaskPersister.notify(task, flush);
8646    }
8647
8648    @Override
8649    public boolean shutdown(int timeout) {
8650        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8651                != PackageManager.PERMISSION_GRANTED) {
8652            throw new SecurityException("Requires permission "
8653                    + android.Manifest.permission.SHUTDOWN);
8654        }
8655
8656        boolean timedout = false;
8657
8658        synchronized(this) {
8659            mShuttingDown = true;
8660            updateEventDispatchingLocked();
8661            timedout = mStackSupervisor.shutdownLocked(timeout);
8662        }
8663
8664        mAppOpsService.shutdown();
8665        mUsageStatsService.shutdown();
8666        mBatteryStatsService.shutdown();
8667        synchronized (this) {
8668            mProcessStats.shutdownLocked();
8669        }
8670        notifyTaskPersisterLocked(null, true);
8671
8672        return timedout;
8673    }
8674
8675    public final void activitySlept(IBinder token) {
8676        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8677
8678        final long origId = Binder.clearCallingIdentity();
8679
8680        synchronized (this) {
8681            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8682            if (r != null) {
8683                mStackSupervisor.activitySleptLocked(r);
8684            }
8685        }
8686
8687        Binder.restoreCallingIdentity(origId);
8688    }
8689
8690    void logLockScreen(String msg) {
8691        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8692                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8693                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8694                mStackSupervisor.mDismissKeyguardOnNextActivity);
8695    }
8696
8697    private void comeOutOfSleepIfNeededLocked() {
8698        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8699            if (mSleeping) {
8700                mSleeping = false;
8701                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8702            }
8703        }
8704    }
8705
8706    void wakingUp() {
8707        synchronized(this) {
8708            mWentToSleep = false;
8709            updateEventDispatchingLocked();
8710            comeOutOfSleepIfNeededLocked();
8711        }
8712    }
8713
8714    void startRunningVoiceLocked() {
8715        if (!mRunningVoice) {
8716            mRunningVoice = true;
8717            comeOutOfSleepIfNeededLocked();
8718        }
8719    }
8720
8721    private void updateEventDispatchingLocked() {
8722        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8723    }
8724
8725    public void setLockScreenShown(boolean shown) {
8726        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8727                != PackageManager.PERMISSION_GRANTED) {
8728            throw new SecurityException("Requires permission "
8729                    + android.Manifest.permission.DEVICE_POWER);
8730        }
8731
8732        synchronized(this) {
8733            long ident = Binder.clearCallingIdentity();
8734            try {
8735                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8736                mLockScreenShown = shown;
8737                comeOutOfSleepIfNeededLocked();
8738            } finally {
8739                Binder.restoreCallingIdentity(ident);
8740            }
8741        }
8742    }
8743
8744    public void stopAppSwitches() {
8745        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8746                != PackageManager.PERMISSION_GRANTED) {
8747            throw new SecurityException("Requires permission "
8748                    + android.Manifest.permission.STOP_APP_SWITCHES);
8749        }
8750
8751        synchronized(this) {
8752            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8753                    + APP_SWITCH_DELAY_TIME;
8754            mDidAppSwitch = false;
8755            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8756            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8757            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8758        }
8759    }
8760
8761    public void resumeAppSwitches() {
8762        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8763                != PackageManager.PERMISSION_GRANTED) {
8764            throw new SecurityException("Requires permission "
8765                    + android.Manifest.permission.STOP_APP_SWITCHES);
8766        }
8767
8768        synchronized(this) {
8769            // Note that we don't execute any pending app switches... we will
8770            // let those wait until either the timeout, or the next start
8771            // activity request.
8772            mAppSwitchesAllowedTime = 0;
8773        }
8774    }
8775
8776    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8777            String name) {
8778        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8779            return true;
8780        }
8781
8782        final int perm = checkComponentPermission(
8783                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8784                callingUid, -1, true);
8785        if (perm == PackageManager.PERMISSION_GRANTED) {
8786            return true;
8787        }
8788
8789        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8790        return false;
8791    }
8792
8793    public void setDebugApp(String packageName, boolean waitForDebugger,
8794            boolean persistent) {
8795        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8796                "setDebugApp()");
8797
8798        long ident = Binder.clearCallingIdentity();
8799        try {
8800            // Note that this is not really thread safe if there are multiple
8801            // callers into it at the same time, but that's not a situation we
8802            // care about.
8803            if (persistent) {
8804                final ContentResolver resolver = mContext.getContentResolver();
8805                Settings.Global.putString(
8806                    resolver, Settings.Global.DEBUG_APP,
8807                    packageName);
8808                Settings.Global.putInt(
8809                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8810                    waitForDebugger ? 1 : 0);
8811            }
8812
8813            synchronized (this) {
8814                if (!persistent) {
8815                    mOrigDebugApp = mDebugApp;
8816                    mOrigWaitForDebugger = mWaitForDebugger;
8817                }
8818                mDebugApp = packageName;
8819                mWaitForDebugger = waitForDebugger;
8820                mDebugTransient = !persistent;
8821                if (packageName != null) {
8822                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8823                            false, UserHandle.USER_ALL, "set debug app");
8824                }
8825            }
8826        } finally {
8827            Binder.restoreCallingIdentity(ident);
8828        }
8829    }
8830
8831    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8832        synchronized (this) {
8833            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8834            if (!isDebuggable) {
8835                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8836                    throw new SecurityException("Process not debuggable: " + app.packageName);
8837                }
8838            }
8839
8840            mOpenGlTraceApp = processName;
8841        }
8842    }
8843
8844    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8845            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8846        synchronized (this) {
8847            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8848            if (!isDebuggable) {
8849                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8850                    throw new SecurityException("Process not debuggable: " + app.packageName);
8851                }
8852            }
8853            mProfileApp = processName;
8854            mProfileFile = profileFile;
8855            if (mProfileFd != null) {
8856                try {
8857                    mProfileFd.close();
8858                } catch (IOException e) {
8859                }
8860                mProfileFd = null;
8861            }
8862            mProfileFd = profileFd;
8863            mProfileType = 0;
8864            mAutoStopProfiler = autoStopProfiler;
8865        }
8866    }
8867
8868    @Override
8869    public void setAlwaysFinish(boolean enabled) {
8870        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8871                "setAlwaysFinish()");
8872
8873        Settings.Global.putInt(
8874                mContext.getContentResolver(),
8875                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8876
8877        synchronized (this) {
8878            mAlwaysFinishActivities = enabled;
8879        }
8880    }
8881
8882    @Override
8883    public void setActivityController(IActivityController controller) {
8884        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8885                "setActivityController()");
8886        synchronized (this) {
8887            mController = controller;
8888            Watchdog.getInstance().setActivityController(controller);
8889        }
8890    }
8891
8892    @Override
8893    public void setUserIsMonkey(boolean userIsMonkey) {
8894        synchronized (this) {
8895            synchronized (mPidsSelfLocked) {
8896                final int callingPid = Binder.getCallingPid();
8897                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8898                if (precessRecord == null) {
8899                    throw new SecurityException("Unknown process: " + callingPid);
8900                }
8901                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8902                    throw new SecurityException("Only an instrumentation process "
8903                            + "with a UiAutomation can call setUserIsMonkey");
8904                }
8905            }
8906            mUserIsMonkey = userIsMonkey;
8907        }
8908    }
8909
8910    @Override
8911    public boolean isUserAMonkey() {
8912        synchronized (this) {
8913            // If there is a controller also implies the user is a monkey.
8914            return (mUserIsMonkey || mController != null);
8915        }
8916    }
8917
8918    public void requestBugReport() {
8919        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8920        SystemProperties.set("ctl.start", "bugreport");
8921    }
8922
8923    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8924        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8925    }
8926
8927    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8928        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8929            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8930        }
8931        return KEY_DISPATCHING_TIMEOUT;
8932    }
8933
8934    @Override
8935    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8936        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8937                != PackageManager.PERMISSION_GRANTED) {
8938            throw new SecurityException("Requires permission "
8939                    + android.Manifest.permission.FILTER_EVENTS);
8940        }
8941        ProcessRecord proc;
8942        long timeout;
8943        synchronized (this) {
8944            synchronized (mPidsSelfLocked) {
8945                proc = mPidsSelfLocked.get(pid);
8946            }
8947            timeout = getInputDispatchingTimeoutLocked(proc);
8948        }
8949
8950        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8951            return -1;
8952        }
8953
8954        return timeout;
8955    }
8956
8957    /**
8958     * Handle input dispatching timeouts.
8959     * Returns whether input dispatching should be aborted or not.
8960     */
8961    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8962            final ActivityRecord activity, final ActivityRecord parent,
8963            final boolean aboveSystem, String reason) {
8964        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8965                != PackageManager.PERMISSION_GRANTED) {
8966            throw new SecurityException("Requires permission "
8967                    + android.Manifest.permission.FILTER_EVENTS);
8968        }
8969
8970        final String annotation;
8971        if (reason == null) {
8972            annotation = "Input dispatching timed out";
8973        } else {
8974            annotation = "Input dispatching timed out (" + reason + ")";
8975        }
8976
8977        if (proc != null) {
8978            synchronized (this) {
8979                if (proc.debugging) {
8980                    return false;
8981                }
8982
8983                if (mDidDexOpt) {
8984                    // Give more time since we were dexopting.
8985                    mDidDexOpt = false;
8986                    return false;
8987                }
8988
8989                if (proc.instrumentationClass != null) {
8990                    Bundle info = new Bundle();
8991                    info.putString("shortMsg", "keyDispatchingTimedOut");
8992                    info.putString("longMsg", annotation);
8993                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8994                    return true;
8995                }
8996            }
8997            mHandler.post(new Runnable() {
8998                @Override
8999                public void run() {
9000                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9001                }
9002            });
9003        }
9004
9005        return true;
9006    }
9007
9008    public Bundle getAssistContextExtras(int requestType) {
9009        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9010                "getAssistContextExtras()");
9011        PendingAssistExtras pae;
9012        Bundle extras = new Bundle();
9013        synchronized (this) {
9014            ActivityRecord activity = getFocusedStack().mResumedActivity;
9015            if (activity == null) {
9016                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9017                return null;
9018            }
9019            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9020            if (activity.app == null || activity.app.thread == null) {
9021                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9022                return extras;
9023            }
9024            if (activity.app.pid == Binder.getCallingPid()) {
9025                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9026                return extras;
9027            }
9028            pae = new PendingAssistExtras(activity);
9029            try {
9030                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9031                        requestType);
9032                mPendingAssistExtras.add(pae);
9033                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9034            } catch (RemoteException e) {
9035                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9036                return extras;
9037            }
9038        }
9039        synchronized (pae) {
9040            while (!pae.haveResult) {
9041                try {
9042                    pae.wait();
9043                } catch (InterruptedException e) {
9044                }
9045            }
9046            if (pae.result != null) {
9047                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9048            }
9049        }
9050        synchronized (this) {
9051            mPendingAssistExtras.remove(pae);
9052            mHandler.removeCallbacks(pae);
9053        }
9054        return extras;
9055    }
9056
9057    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9058        PendingAssistExtras pae = (PendingAssistExtras)token;
9059        synchronized (pae) {
9060            pae.result = extras;
9061            pae.haveResult = true;
9062            pae.notifyAll();
9063        }
9064    }
9065
9066    public void registerProcessObserver(IProcessObserver observer) {
9067        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9068                "registerProcessObserver()");
9069        synchronized (this) {
9070            mProcessObservers.register(observer);
9071        }
9072    }
9073
9074    @Override
9075    public void unregisterProcessObserver(IProcessObserver observer) {
9076        synchronized (this) {
9077            mProcessObservers.unregister(observer);
9078        }
9079    }
9080
9081    @Override
9082    public boolean convertFromTranslucent(IBinder token) {
9083        final long origId = Binder.clearCallingIdentity();
9084        try {
9085            synchronized (this) {
9086                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9087                if (r == null) {
9088                    return false;
9089                }
9090                if (r.changeWindowTranslucency(true)) {
9091                    mWindowManager.setAppFullscreen(token, true);
9092                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9093                    return true;
9094                }
9095                return false;
9096            }
9097        } finally {
9098            Binder.restoreCallingIdentity(origId);
9099        }
9100    }
9101
9102    @Override
9103    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9104        final long origId = Binder.clearCallingIdentity();
9105        try {
9106            synchronized (this) {
9107                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9108                if (r == null) {
9109                    return false;
9110                }
9111                if (r.changeWindowTranslucency(false)) {
9112                    r.task.stack.convertToTranslucent(r, options);
9113                    mWindowManager.setAppFullscreen(token, false);
9114                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9115                    return true;
9116                }
9117                return false;
9118            }
9119        } finally {
9120            Binder.restoreCallingIdentity(origId);
9121        }
9122    }
9123
9124    @Override
9125    public ActivityOptions getActivityOptions(IBinder token) {
9126        final long origId = Binder.clearCallingIdentity();
9127        try {
9128            synchronized (this) {
9129                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9130                if (r != null) {
9131                    final ActivityOptions activityOptions = r.pendingOptions;
9132                    r.pendingOptions = null;
9133                    return activityOptions;
9134                }
9135                return null;
9136            }
9137        } finally {
9138            Binder.restoreCallingIdentity(origId);
9139        }
9140    }
9141
9142    @Override
9143    public void setImmersive(IBinder token, boolean immersive) {
9144        synchronized(this) {
9145            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9146            if (r == null) {
9147                throw new IllegalArgumentException();
9148            }
9149            r.immersive = immersive;
9150
9151            // update associated state if we're frontmost
9152            if (r == mFocusedActivity) {
9153                if (DEBUG_IMMERSIVE) {
9154                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9155                }
9156                applyUpdateLockStateLocked(r);
9157            }
9158        }
9159    }
9160
9161    @Override
9162    public boolean isImmersive(IBinder token) {
9163        synchronized (this) {
9164            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9165            if (r == null) {
9166                throw new IllegalArgumentException();
9167            }
9168            return r.immersive;
9169        }
9170    }
9171
9172    public boolean isTopActivityImmersive() {
9173        enforceNotIsolatedCaller("startActivity");
9174        synchronized (this) {
9175            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9176            return (r != null) ? r.immersive : false;
9177        }
9178    }
9179
9180    public final void enterSafeMode() {
9181        synchronized(this) {
9182            // It only makes sense to do this before the system is ready
9183            // and started launching other packages.
9184            if (!mSystemReady) {
9185                try {
9186                    AppGlobals.getPackageManager().enterSafeMode();
9187                } catch (RemoteException e) {
9188                }
9189            }
9190
9191            mSafeMode = true;
9192        }
9193    }
9194
9195    public final void showSafeModeOverlay() {
9196        View v = LayoutInflater.from(mContext).inflate(
9197                com.android.internal.R.layout.safe_mode, null);
9198        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9199        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9200        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9201        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9202        lp.gravity = Gravity.BOTTOM | Gravity.START;
9203        lp.format = v.getBackground().getOpacity();
9204        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9205                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9206        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9207        ((WindowManager)mContext.getSystemService(
9208                Context.WINDOW_SERVICE)).addView(v, lp);
9209    }
9210
9211    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9212        if (!(sender instanceof PendingIntentRecord)) {
9213            return;
9214        }
9215        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9216        synchronized (stats) {
9217            if (mBatteryStatsService.isOnBattery()) {
9218                mBatteryStatsService.enforceCallingPermission();
9219                PendingIntentRecord rec = (PendingIntentRecord)sender;
9220                int MY_UID = Binder.getCallingUid();
9221                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9222                BatteryStatsImpl.Uid.Pkg pkg =
9223                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9224                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9225                pkg.incWakeupsLocked();
9226            }
9227        }
9228    }
9229
9230    public boolean killPids(int[] pids, String pReason, boolean secure) {
9231        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9232            throw new SecurityException("killPids only available to the system");
9233        }
9234        String reason = (pReason == null) ? "Unknown" : pReason;
9235        // XXX Note: don't acquire main activity lock here, because the window
9236        // manager calls in with its locks held.
9237
9238        boolean killed = false;
9239        synchronized (mPidsSelfLocked) {
9240            int[] types = new int[pids.length];
9241            int worstType = 0;
9242            for (int i=0; i<pids.length; i++) {
9243                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9244                if (proc != null) {
9245                    int type = proc.setAdj;
9246                    types[i] = type;
9247                    if (type > worstType) {
9248                        worstType = type;
9249                    }
9250                }
9251            }
9252
9253            // If the worst oom_adj is somewhere in the cached proc LRU range,
9254            // then constrain it so we will kill all cached procs.
9255            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9256                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9257                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9258            }
9259
9260            // If this is not a secure call, don't let it kill processes that
9261            // are important.
9262            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9263                worstType = ProcessList.SERVICE_ADJ;
9264            }
9265
9266            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9267            for (int i=0; i<pids.length; i++) {
9268                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9269                if (proc == null) {
9270                    continue;
9271                }
9272                int adj = proc.setAdj;
9273                if (adj >= worstType && !proc.killedByAm) {
9274                    killUnneededProcessLocked(proc, reason);
9275                    killed = true;
9276                }
9277            }
9278        }
9279        return killed;
9280    }
9281
9282    @Override
9283    public void killUid(int uid, String reason) {
9284        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9285            throw new SecurityException("killUid only available to the system");
9286        }
9287        synchronized (this) {
9288            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9289                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9290                    reason != null ? reason : "kill uid");
9291        }
9292    }
9293
9294    @Override
9295    public boolean killProcessesBelowForeground(String reason) {
9296        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9297            throw new SecurityException("killProcessesBelowForeground() only available to system");
9298        }
9299
9300        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9301    }
9302
9303    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9304        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9305            throw new SecurityException("killProcessesBelowAdj() only available to system");
9306        }
9307
9308        boolean killed = false;
9309        synchronized (mPidsSelfLocked) {
9310            final int size = mPidsSelfLocked.size();
9311            for (int i = 0; i < size; i++) {
9312                final int pid = mPidsSelfLocked.keyAt(i);
9313                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9314                if (proc == null) continue;
9315
9316                final int adj = proc.setAdj;
9317                if (adj > belowAdj && !proc.killedByAm) {
9318                    killUnneededProcessLocked(proc, reason);
9319                    killed = true;
9320                }
9321            }
9322        }
9323        return killed;
9324    }
9325
9326    @Override
9327    public void hang(final IBinder who, boolean allowRestart) {
9328        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9329                != PackageManager.PERMISSION_GRANTED) {
9330            throw new SecurityException("Requires permission "
9331                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9332        }
9333
9334        final IBinder.DeathRecipient death = new DeathRecipient() {
9335            @Override
9336            public void binderDied() {
9337                synchronized (this) {
9338                    notifyAll();
9339                }
9340            }
9341        };
9342
9343        try {
9344            who.linkToDeath(death, 0);
9345        } catch (RemoteException e) {
9346            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9347            return;
9348        }
9349
9350        synchronized (this) {
9351            Watchdog.getInstance().setAllowRestart(allowRestart);
9352            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9353            synchronized (death) {
9354                while (who.isBinderAlive()) {
9355                    try {
9356                        death.wait();
9357                    } catch (InterruptedException e) {
9358                    }
9359                }
9360            }
9361            Watchdog.getInstance().setAllowRestart(true);
9362        }
9363    }
9364
9365    @Override
9366    public void restart() {
9367        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9368                != PackageManager.PERMISSION_GRANTED) {
9369            throw new SecurityException("Requires permission "
9370                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9371        }
9372
9373        Log.i(TAG, "Sending shutdown broadcast...");
9374
9375        BroadcastReceiver br = new BroadcastReceiver() {
9376            @Override public void onReceive(Context context, Intent intent) {
9377                // Now the broadcast is done, finish up the low-level shutdown.
9378                Log.i(TAG, "Shutting down activity manager...");
9379                shutdown(10000);
9380                Log.i(TAG, "Shutdown complete, restarting!");
9381                Process.killProcess(Process.myPid());
9382                System.exit(10);
9383            }
9384        };
9385
9386        // First send the high-level shut down broadcast.
9387        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9388        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9389        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9390        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9391        mContext.sendOrderedBroadcastAsUser(intent,
9392                UserHandle.ALL, null, br, mHandler, 0, null, null);
9393        */
9394        br.onReceive(mContext, intent);
9395    }
9396
9397    private long getLowRamTimeSinceIdle(long now) {
9398        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9399    }
9400
9401    @Override
9402    public void performIdleMaintenance() {
9403        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9404                != PackageManager.PERMISSION_GRANTED) {
9405            throw new SecurityException("Requires permission "
9406                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9407        }
9408
9409        synchronized (this) {
9410            final long now = SystemClock.uptimeMillis();
9411            final long timeSinceLastIdle = now - mLastIdleTime;
9412            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9413            mLastIdleTime = now;
9414            mLowRamTimeSinceLastIdle = 0;
9415            if (mLowRamStartTime != 0) {
9416                mLowRamStartTime = now;
9417            }
9418
9419            StringBuilder sb = new StringBuilder(128);
9420            sb.append("Idle maintenance over ");
9421            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9422            sb.append(" low RAM for ");
9423            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9424            Slog.i(TAG, sb.toString());
9425
9426            // If at least 1/3 of our time since the last idle period has been spent
9427            // with RAM low, then we want to kill processes.
9428            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9429
9430            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9431                ProcessRecord proc = mLruProcesses.get(i);
9432                if (proc.notCachedSinceIdle) {
9433                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9434                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9435                        if (doKilling && proc.initialIdlePss != 0
9436                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9437                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9438                                    + " from " + proc.initialIdlePss + ")");
9439                        }
9440                    }
9441                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9442                    proc.notCachedSinceIdle = true;
9443                    proc.initialIdlePss = 0;
9444                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9445                            isSleeping(), now);
9446                }
9447            }
9448
9449            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9450            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9451        }
9452    }
9453
9454    private void retrieveSettings() {
9455        final ContentResolver resolver = mContext.getContentResolver();
9456        String debugApp = Settings.Global.getString(
9457            resolver, Settings.Global.DEBUG_APP);
9458        boolean waitForDebugger = Settings.Global.getInt(
9459            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9460        boolean alwaysFinishActivities = Settings.Global.getInt(
9461            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9462        boolean forceRtl = Settings.Global.getInt(
9463                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9464        // Transfer any global setting for forcing RTL layout, into a System Property
9465        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9466
9467        Configuration configuration = new Configuration();
9468        Settings.System.getConfiguration(resolver, configuration);
9469        if (forceRtl) {
9470            // This will take care of setting the correct layout direction flags
9471            configuration.setLayoutDirection(configuration.locale);
9472        }
9473
9474        synchronized (this) {
9475            mDebugApp = mOrigDebugApp = debugApp;
9476            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9477            mAlwaysFinishActivities = alwaysFinishActivities;
9478            // This happens before any activities are started, so we can
9479            // change mConfiguration in-place.
9480            updateConfigurationLocked(configuration, null, false, true);
9481            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9482        }
9483    }
9484
9485    public boolean testIsSystemReady() {
9486        // no need to synchronize(this) just to read & return the value
9487        return mSystemReady;
9488    }
9489
9490    private static File getCalledPreBootReceiversFile() {
9491        File dataDir = Environment.getDataDirectory();
9492        File systemDir = new File(dataDir, "system");
9493        File fname = new File(systemDir, "called_pre_boots.dat");
9494        return fname;
9495    }
9496
9497    static final int LAST_DONE_VERSION = 10000;
9498
9499    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9500        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9501        File file = getCalledPreBootReceiversFile();
9502        FileInputStream fis = null;
9503        try {
9504            fis = new FileInputStream(file);
9505            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9506            int fvers = dis.readInt();
9507            if (fvers == LAST_DONE_VERSION) {
9508                String vers = dis.readUTF();
9509                String codename = dis.readUTF();
9510                String build = dis.readUTF();
9511                if (android.os.Build.VERSION.RELEASE.equals(vers)
9512                        && android.os.Build.VERSION.CODENAME.equals(codename)
9513                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9514                    int num = dis.readInt();
9515                    while (num > 0) {
9516                        num--;
9517                        String pkg = dis.readUTF();
9518                        String cls = dis.readUTF();
9519                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9520                    }
9521                }
9522            }
9523        } catch (FileNotFoundException e) {
9524        } catch (IOException e) {
9525            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9526        } finally {
9527            if (fis != null) {
9528                try {
9529                    fis.close();
9530                } catch (IOException e) {
9531                }
9532            }
9533        }
9534        return lastDoneReceivers;
9535    }
9536
9537    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9538        File file = getCalledPreBootReceiversFile();
9539        FileOutputStream fos = null;
9540        DataOutputStream dos = null;
9541        try {
9542            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9543            fos = new FileOutputStream(file);
9544            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9545            dos.writeInt(LAST_DONE_VERSION);
9546            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9547            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9548            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9549            dos.writeInt(list.size());
9550            for (int i=0; i<list.size(); i++) {
9551                dos.writeUTF(list.get(i).getPackageName());
9552                dos.writeUTF(list.get(i).getClassName());
9553            }
9554        } catch (IOException e) {
9555            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9556            file.delete();
9557        } finally {
9558            FileUtils.sync(fos);
9559            if (dos != null) {
9560                try {
9561                    dos.close();
9562                } catch (IOException e) {
9563                    // TODO Auto-generated catch block
9564                    e.printStackTrace();
9565                }
9566            }
9567        }
9568    }
9569
9570    public void systemReady(final Runnable goingCallback) {
9571        synchronized(this) {
9572            if (mSystemReady) {
9573                if (goingCallback != null) goingCallback.run();
9574                return;
9575            }
9576
9577            mRecentTasks = mTaskPersister.restoreTasksLocked();
9578            if (!mRecentTasks.isEmpty()) {
9579                mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9580            }
9581            mTaskPersister.startPersisting();
9582
9583            // Check to see if there are any update receivers to run.
9584            if (!mDidUpdate) {
9585                if (mWaitingUpdate) {
9586                    return;
9587                }
9588                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9589                List<ResolveInfo> ris = null;
9590                try {
9591                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9592                            intent, null, 0, 0);
9593                } catch (RemoteException e) {
9594                }
9595                if (ris != null) {
9596                    for (int i=ris.size()-1; i>=0; i--) {
9597                        if ((ris.get(i).activityInfo.applicationInfo.flags
9598                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9599                            ris.remove(i);
9600                        }
9601                    }
9602                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9603
9604                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9605
9606                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9607                    for (int i=0; i<ris.size(); i++) {
9608                        ActivityInfo ai = ris.get(i).activityInfo;
9609                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9610                        if (lastDoneReceivers.contains(comp)) {
9611                            // We already did the pre boot receiver for this app with the current
9612                            // platform version, so don't do it again...
9613                            ris.remove(i);
9614                            i--;
9615                            // ...however, do keep it as one that has been done, so we don't
9616                            // forget about it when rewriting the file of last done receivers.
9617                            doneReceivers.add(comp);
9618                        }
9619                    }
9620
9621                    final int[] users = getUsersLocked();
9622                    for (int i=0; i<ris.size(); i++) {
9623                        ActivityInfo ai = ris.get(i).activityInfo;
9624                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9625                        doneReceivers.add(comp);
9626                        intent.setComponent(comp);
9627                        for (int j=0; j<users.length; j++) {
9628                            IIntentReceiver finisher = null;
9629                            if (i == ris.size()-1 && j == users.length-1) {
9630                                finisher = new IIntentReceiver.Stub() {
9631                                    public void performReceive(Intent intent, int resultCode,
9632                                            String data, Bundle extras, boolean ordered,
9633                                            boolean sticky, int sendingUser) {
9634                                        // The raw IIntentReceiver interface is called
9635                                        // with the AM lock held, so redispatch to
9636                                        // execute our code without the lock.
9637                                        mHandler.post(new Runnable() {
9638                                            public void run() {
9639                                                synchronized (ActivityManagerService.this) {
9640                                                    mDidUpdate = true;
9641                                                }
9642                                                writeLastDonePreBootReceivers(doneReceivers);
9643                                                showBootMessage(mContext.getText(
9644                                                        R.string.android_upgrading_complete),
9645                                                        false);
9646                                                systemReady(goingCallback);
9647                                            }
9648                                        });
9649                                    }
9650                                };
9651                            }
9652                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9653                                    + " for user " + users[j]);
9654                            broadcastIntentLocked(null, null, intent, null, finisher,
9655                                    0, null, null, null, AppOpsManager.OP_NONE,
9656                                    true, false, MY_PID, Process.SYSTEM_UID,
9657                                    users[j]);
9658                            if (finisher != null) {
9659                                mWaitingUpdate = true;
9660                            }
9661                        }
9662                    }
9663                }
9664                if (mWaitingUpdate) {
9665                    return;
9666                }
9667                mDidUpdate = true;
9668            }
9669
9670            mAppOpsService.systemReady();
9671            mUsageStatsService.systemReady();
9672            mSystemReady = true;
9673        }
9674
9675        ArrayList<ProcessRecord> procsToKill = null;
9676        synchronized(mPidsSelfLocked) {
9677            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9678                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9679                if (!isAllowedWhileBooting(proc.info)){
9680                    if (procsToKill == null) {
9681                        procsToKill = new ArrayList<ProcessRecord>();
9682                    }
9683                    procsToKill.add(proc);
9684                }
9685            }
9686        }
9687
9688        synchronized(this) {
9689            if (procsToKill != null) {
9690                for (int i=procsToKill.size()-1; i>=0; i--) {
9691                    ProcessRecord proc = procsToKill.get(i);
9692                    Slog.i(TAG, "Removing system update proc: " + proc);
9693                    removeProcessLocked(proc, true, false, "system update done");
9694                }
9695            }
9696
9697            // Now that we have cleaned up any update processes, we
9698            // are ready to start launching real processes and know that
9699            // we won't trample on them any more.
9700            mProcessesReady = true;
9701        }
9702
9703        Slog.i(TAG, "System now ready");
9704        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9705            SystemClock.uptimeMillis());
9706
9707        synchronized(this) {
9708            // Make sure we have no pre-ready processes sitting around.
9709
9710            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9711                ResolveInfo ri = mContext.getPackageManager()
9712                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9713                                STOCK_PM_FLAGS);
9714                CharSequence errorMsg = null;
9715                if (ri != null) {
9716                    ActivityInfo ai = ri.activityInfo;
9717                    ApplicationInfo app = ai.applicationInfo;
9718                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9719                        mTopAction = Intent.ACTION_FACTORY_TEST;
9720                        mTopData = null;
9721                        mTopComponent = new ComponentName(app.packageName,
9722                                ai.name);
9723                    } else {
9724                        errorMsg = mContext.getResources().getText(
9725                                com.android.internal.R.string.factorytest_not_system);
9726                    }
9727                } else {
9728                    errorMsg = mContext.getResources().getText(
9729                            com.android.internal.R.string.factorytest_no_action);
9730                }
9731                if (errorMsg != null) {
9732                    mTopAction = null;
9733                    mTopData = null;
9734                    mTopComponent = null;
9735                    Message msg = Message.obtain();
9736                    msg.what = SHOW_FACTORY_ERROR_MSG;
9737                    msg.getData().putCharSequence("msg", errorMsg);
9738                    mHandler.sendMessage(msg);
9739                }
9740            }
9741        }
9742
9743        retrieveSettings();
9744
9745        synchronized (this) {
9746            readGrantedUriPermissionsLocked();
9747        }
9748
9749        if (goingCallback != null) goingCallback.run();
9750
9751        mSystemServiceManager.startUser(mCurrentUserId);
9752
9753        synchronized (this) {
9754            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9755                try {
9756                    List apps = AppGlobals.getPackageManager().
9757                        getPersistentApplications(STOCK_PM_FLAGS);
9758                    if (apps != null) {
9759                        int N = apps.size();
9760                        int i;
9761                        for (i=0; i<N; i++) {
9762                            ApplicationInfo info
9763                                = (ApplicationInfo)apps.get(i);
9764                            if (info != null &&
9765                                    !info.packageName.equals("android")) {
9766                                addAppLocked(info, false);
9767                            }
9768                        }
9769                    }
9770                } catch (RemoteException ex) {
9771                    // pm is in same process, this will never happen.
9772                }
9773            }
9774
9775            // Start up initial activity.
9776            mBooting = true;
9777
9778            try {
9779                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9780                    Message msg = Message.obtain();
9781                    msg.what = SHOW_UID_ERROR_MSG;
9782                    mHandler.sendMessage(msg);
9783                }
9784            } catch (RemoteException e) {
9785            }
9786
9787            long ident = Binder.clearCallingIdentity();
9788            try {
9789                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9790                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9791                        | Intent.FLAG_RECEIVER_FOREGROUND);
9792                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9793                broadcastIntentLocked(null, null, intent,
9794                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9795                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9796                intent = new Intent(Intent.ACTION_USER_STARTING);
9797                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9798                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9799                broadcastIntentLocked(null, null, intent,
9800                        null, new IIntentReceiver.Stub() {
9801                            @Override
9802                            public void performReceive(Intent intent, int resultCode, String data,
9803                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9804                                    throws RemoteException {
9805                            }
9806                        }, 0, null, null,
9807                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9808                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9809            } catch (Throwable t) {
9810                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9811            } finally {
9812                Binder.restoreCallingIdentity(ident);
9813            }
9814            mStackSupervisor.resumeTopActivitiesLocked();
9815            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9816        }
9817    }
9818
9819    private boolean makeAppCrashingLocked(ProcessRecord app,
9820            String shortMsg, String longMsg, String stackTrace) {
9821        app.crashing = true;
9822        app.crashingReport = generateProcessError(app,
9823                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9824        startAppProblemLocked(app);
9825        app.stopFreezingAllLocked();
9826        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9827    }
9828
9829    private void makeAppNotRespondingLocked(ProcessRecord app,
9830            String activity, String shortMsg, String longMsg) {
9831        app.notResponding = true;
9832        app.notRespondingReport = generateProcessError(app,
9833                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9834                activity, shortMsg, longMsg, null);
9835        startAppProblemLocked(app);
9836        app.stopFreezingAllLocked();
9837    }
9838
9839    /**
9840     * Generate a process error record, suitable for attachment to a ProcessRecord.
9841     *
9842     * @param app The ProcessRecord in which the error occurred.
9843     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9844     *                      ActivityManager.AppErrorStateInfo
9845     * @param activity The activity associated with the crash, if known.
9846     * @param shortMsg Short message describing the crash.
9847     * @param longMsg Long message describing the crash.
9848     * @param stackTrace Full crash stack trace, may be null.
9849     *
9850     * @return Returns a fully-formed AppErrorStateInfo record.
9851     */
9852    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9853            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9854        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9855
9856        report.condition = condition;
9857        report.processName = app.processName;
9858        report.pid = app.pid;
9859        report.uid = app.info.uid;
9860        report.tag = activity;
9861        report.shortMsg = shortMsg;
9862        report.longMsg = longMsg;
9863        report.stackTrace = stackTrace;
9864
9865        return report;
9866    }
9867
9868    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9869        synchronized (this) {
9870            app.crashing = false;
9871            app.crashingReport = null;
9872            app.notResponding = false;
9873            app.notRespondingReport = null;
9874            if (app.anrDialog == fromDialog) {
9875                app.anrDialog = null;
9876            }
9877            if (app.waitDialog == fromDialog) {
9878                app.waitDialog = null;
9879            }
9880            if (app.pid > 0 && app.pid != MY_PID) {
9881                handleAppCrashLocked(app, null, null, null);
9882                killUnneededProcessLocked(app, "user request after error");
9883            }
9884        }
9885    }
9886
9887    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9888            String stackTrace) {
9889        long now = SystemClock.uptimeMillis();
9890
9891        Long crashTime;
9892        if (!app.isolated) {
9893            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9894        } else {
9895            crashTime = null;
9896        }
9897        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9898            // This process loses!
9899            Slog.w(TAG, "Process " + app.info.processName
9900                    + " has crashed too many times: killing!");
9901            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9902                    app.userId, app.info.processName, app.uid);
9903            mStackSupervisor.handleAppCrashLocked(app);
9904            if (!app.persistent) {
9905                // We don't want to start this process again until the user
9906                // explicitly does so...  but for persistent process, we really
9907                // need to keep it running.  If a persistent process is actually
9908                // repeatedly crashing, then badness for everyone.
9909                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9910                        app.info.processName);
9911                if (!app.isolated) {
9912                    // XXX We don't have a way to mark isolated processes
9913                    // as bad, since they don't have a peristent identity.
9914                    mBadProcesses.put(app.info.processName, app.uid,
9915                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9916                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9917                }
9918                app.bad = true;
9919                app.removed = true;
9920                // Don't let services in this process be restarted and potentially
9921                // annoy the user repeatedly.  Unless it is persistent, since those
9922                // processes run critical code.
9923                removeProcessLocked(app, false, false, "crash");
9924                mStackSupervisor.resumeTopActivitiesLocked();
9925                return false;
9926            }
9927            mStackSupervisor.resumeTopActivitiesLocked();
9928        } else {
9929            mStackSupervisor.finishTopRunningActivityLocked(app);
9930        }
9931
9932        // Bump up the crash count of any services currently running in the proc.
9933        for (int i=app.services.size()-1; i>=0; i--) {
9934            // Any services running in the application need to be placed
9935            // back in the pending list.
9936            ServiceRecord sr = app.services.valueAt(i);
9937            sr.crashCount++;
9938        }
9939
9940        // If the crashing process is what we consider to be the "home process" and it has been
9941        // replaced by a third-party app, clear the package preferred activities from packages
9942        // with a home activity running in the process to prevent a repeatedly crashing app
9943        // from blocking the user to manually clear the list.
9944        final ArrayList<ActivityRecord> activities = app.activities;
9945        if (app == mHomeProcess && activities.size() > 0
9946                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9947            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9948                final ActivityRecord r = activities.get(activityNdx);
9949                if (r.isHomeActivity()) {
9950                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9951                    try {
9952                        ActivityThread.getPackageManager()
9953                                .clearPackagePreferredActivities(r.packageName);
9954                    } catch (RemoteException c) {
9955                        // pm is in same process, this will never happen.
9956                    }
9957                }
9958            }
9959        }
9960
9961        if (!app.isolated) {
9962            // XXX Can't keep track of crash times for isolated processes,
9963            // because they don't have a perisistent identity.
9964            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9965        }
9966
9967        return true;
9968    }
9969
9970    void startAppProblemLocked(ProcessRecord app) {
9971        if (app.userId == mCurrentUserId) {
9972            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9973                    mContext, app.info.packageName, app.info.flags);
9974        } else {
9975            // If this app is not running under the current user, then we
9976            // can't give it a report button because that would require
9977            // launching the report UI under a different user.
9978            app.errorReportReceiver = null;
9979        }
9980        skipCurrentReceiverLocked(app);
9981    }
9982
9983    void skipCurrentReceiverLocked(ProcessRecord app) {
9984        for (BroadcastQueue queue : mBroadcastQueues) {
9985            queue.skipCurrentReceiverLocked(app);
9986        }
9987    }
9988
9989    /**
9990     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9991     * The application process will exit immediately after this call returns.
9992     * @param app object of the crashing app, null for the system server
9993     * @param crashInfo describing the exception
9994     */
9995    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9996        ProcessRecord r = findAppProcess(app, "Crash");
9997        final String processName = app == null ? "system_server"
9998                : (r == null ? "unknown" : r.processName);
9999
10000        handleApplicationCrashInner("crash", r, processName, crashInfo);
10001    }
10002
10003    /* Native crash reporting uses this inner version because it needs to be somewhat
10004     * decoupled from the AM-managed cleanup lifecycle
10005     */
10006    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10007            ApplicationErrorReport.CrashInfo crashInfo) {
10008        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10009                UserHandle.getUserId(Binder.getCallingUid()), processName,
10010                r == null ? -1 : r.info.flags,
10011                crashInfo.exceptionClassName,
10012                crashInfo.exceptionMessage,
10013                crashInfo.throwFileName,
10014                crashInfo.throwLineNumber);
10015
10016        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10017
10018        crashApplication(r, crashInfo);
10019    }
10020
10021    public void handleApplicationStrictModeViolation(
10022            IBinder app,
10023            int violationMask,
10024            StrictMode.ViolationInfo info) {
10025        ProcessRecord r = findAppProcess(app, "StrictMode");
10026        if (r == null) {
10027            return;
10028        }
10029
10030        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10031            Integer stackFingerprint = info.hashCode();
10032            boolean logIt = true;
10033            synchronized (mAlreadyLoggedViolatedStacks) {
10034                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10035                    logIt = false;
10036                    // TODO: sub-sample into EventLog for these, with
10037                    // the info.durationMillis?  Then we'd get
10038                    // the relative pain numbers, without logging all
10039                    // the stack traces repeatedly.  We'd want to do
10040                    // likewise in the client code, which also does
10041                    // dup suppression, before the Binder call.
10042                } else {
10043                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10044                        mAlreadyLoggedViolatedStacks.clear();
10045                    }
10046                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10047                }
10048            }
10049            if (logIt) {
10050                logStrictModeViolationToDropBox(r, info);
10051            }
10052        }
10053
10054        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10055            AppErrorResult result = new AppErrorResult();
10056            synchronized (this) {
10057                final long origId = Binder.clearCallingIdentity();
10058
10059                Message msg = Message.obtain();
10060                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10061                HashMap<String, Object> data = new HashMap<String, Object>();
10062                data.put("result", result);
10063                data.put("app", r);
10064                data.put("violationMask", violationMask);
10065                data.put("info", info);
10066                msg.obj = data;
10067                mHandler.sendMessage(msg);
10068
10069                Binder.restoreCallingIdentity(origId);
10070            }
10071            int res = result.get();
10072            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10073        }
10074    }
10075
10076    // Depending on the policy in effect, there could be a bunch of
10077    // these in quick succession so we try to batch these together to
10078    // minimize disk writes, number of dropbox entries, and maximize
10079    // compression, by having more fewer, larger records.
10080    private void logStrictModeViolationToDropBox(
10081            ProcessRecord process,
10082            StrictMode.ViolationInfo info) {
10083        if (info == null) {
10084            return;
10085        }
10086        final boolean isSystemApp = process == null ||
10087                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10088                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10089        final String processName = process == null ? "unknown" : process.processName;
10090        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10091        final DropBoxManager dbox = (DropBoxManager)
10092                mContext.getSystemService(Context.DROPBOX_SERVICE);
10093
10094        // Exit early if the dropbox isn't configured to accept this report type.
10095        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10096
10097        boolean bufferWasEmpty;
10098        boolean needsFlush;
10099        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10100        synchronized (sb) {
10101            bufferWasEmpty = sb.length() == 0;
10102            appendDropBoxProcessHeaders(process, processName, sb);
10103            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10104            sb.append("System-App: ").append(isSystemApp).append("\n");
10105            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10106            if (info.violationNumThisLoop != 0) {
10107                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10108            }
10109            if (info.numAnimationsRunning != 0) {
10110                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10111            }
10112            if (info.broadcastIntentAction != null) {
10113                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10114            }
10115            if (info.durationMillis != -1) {
10116                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10117            }
10118            if (info.numInstances != -1) {
10119                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10120            }
10121            if (info.tags != null) {
10122                for (String tag : info.tags) {
10123                    sb.append("Span-Tag: ").append(tag).append("\n");
10124                }
10125            }
10126            sb.append("\n");
10127            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10128                sb.append(info.crashInfo.stackTrace);
10129            }
10130            sb.append("\n");
10131
10132            // Only buffer up to ~64k.  Various logging bits truncate
10133            // things at 128k.
10134            needsFlush = (sb.length() > 64 * 1024);
10135        }
10136
10137        // Flush immediately if the buffer's grown too large, or this
10138        // is a non-system app.  Non-system apps are isolated with a
10139        // different tag & policy and not batched.
10140        //
10141        // Batching is useful during internal testing with
10142        // StrictMode settings turned up high.  Without batching,
10143        // thousands of separate files could be created on boot.
10144        if (!isSystemApp || needsFlush) {
10145            new Thread("Error dump: " + dropboxTag) {
10146                @Override
10147                public void run() {
10148                    String report;
10149                    synchronized (sb) {
10150                        report = sb.toString();
10151                        sb.delete(0, sb.length());
10152                        sb.trimToSize();
10153                    }
10154                    if (report.length() != 0) {
10155                        dbox.addText(dropboxTag, report);
10156                    }
10157                }
10158            }.start();
10159            return;
10160        }
10161
10162        // System app batching:
10163        if (!bufferWasEmpty) {
10164            // An existing dropbox-writing thread is outstanding, so
10165            // we don't need to start it up.  The existing thread will
10166            // catch the buffer appends we just did.
10167            return;
10168        }
10169
10170        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10171        // (After this point, we shouldn't access AMS internal data structures.)
10172        new Thread("Error dump: " + dropboxTag) {
10173            @Override
10174            public void run() {
10175                // 5 second sleep to let stacks arrive and be batched together
10176                try {
10177                    Thread.sleep(5000);  // 5 seconds
10178                } catch (InterruptedException e) {}
10179
10180                String errorReport;
10181                synchronized (mStrictModeBuffer) {
10182                    errorReport = mStrictModeBuffer.toString();
10183                    if (errorReport.length() == 0) {
10184                        return;
10185                    }
10186                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10187                    mStrictModeBuffer.trimToSize();
10188                }
10189                dbox.addText(dropboxTag, errorReport);
10190            }
10191        }.start();
10192    }
10193
10194    /**
10195     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10196     * @param app object of the crashing app, null for the system server
10197     * @param tag reported by the caller
10198     * @param crashInfo describing the context of the error
10199     * @return true if the process should exit immediately (WTF is fatal)
10200     */
10201    public boolean handleApplicationWtf(IBinder app, String tag,
10202            ApplicationErrorReport.CrashInfo crashInfo) {
10203        ProcessRecord r = findAppProcess(app, "WTF");
10204        final String processName = app == null ? "system_server"
10205                : (r == null ? "unknown" : r.processName);
10206
10207        EventLog.writeEvent(EventLogTags.AM_WTF,
10208                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10209                processName,
10210                r == null ? -1 : r.info.flags,
10211                tag, crashInfo.exceptionMessage);
10212
10213        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10214
10215        if (r != null && r.pid != Process.myPid() &&
10216                Settings.Global.getInt(mContext.getContentResolver(),
10217                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10218            crashApplication(r, crashInfo);
10219            return true;
10220        } else {
10221            return false;
10222        }
10223    }
10224
10225    /**
10226     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10227     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10228     */
10229    private ProcessRecord findAppProcess(IBinder app, String reason) {
10230        if (app == null) {
10231            return null;
10232        }
10233
10234        synchronized (this) {
10235            final int NP = mProcessNames.getMap().size();
10236            for (int ip=0; ip<NP; ip++) {
10237                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10238                final int NA = apps.size();
10239                for (int ia=0; ia<NA; ia++) {
10240                    ProcessRecord p = apps.valueAt(ia);
10241                    if (p.thread != null && p.thread.asBinder() == app) {
10242                        return p;
10243                    }
10244                }
10245            }
10246
10247            Slog.w(TAG, "Can't find mystery application for " + reason
10248                    + " from pid=" + Binder.getCallingPid()
10249                    + " uid=" + Binder.getCallingUid() + ": " + app);
10250            return null;
10251        }
10252    }
10253
10254    /**
10255     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10256     * to append various headers to the dropbox log text.
10257     */
10258    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10259            StringBuilder sb) {
10260        // Watchdog thread ends up invoking this function (with
10261        // a null ProcessRecord) to add the stack file to dropbox.
10262        // Do not acquire a lock on this (am) in such cases, as it
10263        // could cause a potential deadlock, if and when watchdog
10264        // is invoked due to unavailability of lock on am and it
10265        // would prevent watchdog from killing system_server.
10266        if (process == null) {
10267            sb.append("Process: ").append(processName).append("\n");
10268            return;
10269        }
10270        // Note: ProcessRecord 'process' is guarded by the service
10271        // instance.  (notably process.pkgList, which could otherwise change
10272        // concurrently during execution of this method)
10273        synchronized (this) {
10274            sb.append("Process: ").append(processName).append("\n");
10275            int flags = process.info.flags;
10276            IPackageManager pm = AppGlobals.getPackageManager();
10277            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10278            for (int ip=0; ip<process.pkgList.size(); ip++) {
10279                String pkg = process.pkgList.keyAt(ip);
10280                sb.append("Package: ").append(pkg);
10281                try {
10282                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10283                    if (pi != null) {
10284                        sb.append(" v").append(pi.versionCode);
10285                        if (pi.versionName != null) {
10286                            sb.append(" (").append(pi.versionName).append(")");
10287                        }
10288                    }
10289                } catch (RemoteException e) {
10290                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10291                }
10292                sb.append("\n");
10293            }
10294        }
10295    }
10296
10297    private static String processClass(ProcessRecord process) {
10298        if (process == null || process.pid == MY_PID) {
10299            return "system_server";
10300        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10301            return "system_app";
10302        } else {
10303            return "data_app";
10304        }
10305    }
10306
10307    /**
10308     * Write a description of an error (crash, WTF, ANR) to the drop box.
10309     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10310     * @param process which caused the error, null means the system server
10311     * @param activity which triggered the error, null if unknown
10312     * @param parent activity related to the error, null if unknown
10313     * @param subject line related to the error, null if absent
10314     * @param report in long form describing the error, null if absent
10315     * @param logFile to include in the report, null if none
10316     * @param crashInfo giving an application stack trace, null if absent
10317     */
10318    public void addErrorToDropBox(String eventType,
10319            ProcessRecord process, String processName, ActivityRecord activity,
10320            ActivityRecord parent, String subject,
10321            final String report, final File logFile,
10322            final ApplicationErrorReport.CrashInfo crashInfo) {
10323        // NOTE -- this must never acquire the ActivityManagerService lock,
10324        // otherwise the watchdog may be prevented from resetting the system.
10325
10326        final String dropboxTag = processClass(process) + "_" + eventType;
10327        final DropBoxManager dbox = (DropBoxManager)
10328                mContext.getSystemService(Context.DROPBOX_SERVICE);
10329
10330        // Exit early if the dropbox isn't configured to accept this report type.
10331        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10332
10333        final StringBuilder sb = new StringBuilder(1024);
10334        appendDropBoxProcessHeaders(process, processName, sb);
10335        if (activity != null) {
10336            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10337        }
10338        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10339            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10340        }
10341        if (parent != null && parent != activity) {
10342            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10343        }
10344        if (subject != null) {
10345            sb.append("Subject: ").append(subject).append("\n");
10346        }
10347        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10348        if (Debug.isDebuggerConnected()) {
10349            sb.append("Debugger: Connected\n");
10350        }
10351        sb.append("\n");
10352
10353        // Do the rest in a worker thread to avoid blocking the caller on I/O
10354        // (After this point, we shouldn't access AMS internal data structures.)
10355        Thread worker = new Thread("Error dump: " + dropboxTag) {
10356            @Override
10357            public void run() {
10358                if (report != null) {
10359                    sb.append(report);
10360                }
10361                if (logFile != null) {
10362                    try {
10363                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10364                                    "\n\n[[TRUNCATED]]"));
10365                    } catch (IOException e) {
10366                        Slog.e(TAG, "Error reading " + logFile, e);
10367                    }
10368                }
10369                if (crashInfo != null && crashInfo.stackTrace != null) {
10370                    sb.append(crashInfo.stackTrace);
10371                }
10372
10373                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10374                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10375                if (lines > 0) {
10376                    sb.append("\n");
10377
10378                    // Merge several logcat streams, and take the last N lines
10379                    InputStreamReader input = null;
10380                    try {
10381                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10382                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10383                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10384
10385                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10386                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10387                        input = new InputStreamReader(logcat.getInputStream());
10388
10389                        int num;
10390                        char[] buf = new char[8192];
10391                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10392                    } catch (IOException e) {
10393                        Slog.e(TAG, "Error running logcat", e);
10394                    } finally {
10395                        if (input != null) try { input.close(); } catch (IOException e) {}
10396                    }
10397                }
10398
10399                dbox.addText(dropboxTag, sb.toString());
10400            }
10401        };
10402
10403        if (process == null) {
10404            // If process is null, we are being called from some internal code
10405            // and may be about to die -- run this synchronously.
10406            worker.run();
10407        } else {
10408            worker.start();
10409        }
10410    }
10411
10412    /**
10413     * Bring up the "unexpected error" dialog box for a crashing app.
10414     * Deal with edge cases (intercepts from instrumented applications,
10415     * ActivityController, error intent receivers, that sort of thing).
10416     * @param r the application crashing
10417     * @param crashInfo describing the failure
10418     */
10419    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10420        long timeMillis = System.currentTimeMillis();
10421        String shortMsg = crashInfo.exceptionClassName;
10422        String longMsg = crashInfo.exceptionMessage;
10423        String stackTrace = crashInfo.stackTrace;
10424        if (shortMsg != null && longMsg != null) {
10425            longMsg = shortMsg + ": " + longMsg;
10426        } else if (shortMsg != null) {
10427            longMsg = shortMsg;
10428        }
10429
10430        AppErrorResult result = new AppErrorResult();
10431        synchronized (this) {
10432            if (mController != null) {
10433                try {
10434                    String name = r != null ? r.processName : null;
10435                    int pid = r != null ? r.pid : Binder.getCallingPid();
10436                    if (!mController.appCrashed(name, pid,
10437                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10438                        Slog.w(TAG, "Force-killing crashed app " + name
10439                                + " at watcher's request");
10440                        Process.killProcess(pid);
10441                        return;
10442                    }
10443                } catch (RemoteException e) {
10444                    mController = null;
10445                    Watchdog.getInstance().setActivityController(null);
10446                }
10447            }
10448
10449            final long origId = Binder.clearCallingIdentity();
10450
10451            // If this process is running instrumentation, finish it.
10452            if (r != null && r.instrumentationClass != null) {
10453                Slog.w(TAG, "Error in app " + r.processName
10454                      + " running instrumentation " + r.instrumentationClass + ":");
10455                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10456                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10457                Bundle info = new Bundle();
10458                info.putString("shortMsg", shortMsg);
10459                info.putString("longMsg", longMsg);
10460                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10461                Binder.restoreCallingIdentity(origId);
10462                return;
10463            }
10464
10465            // If we can't identify the process or it's already exceeded its crash quota,
10466            // quit right away without showing a crash dialog.
10467            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10468                Binder.restoreCallingIdentity(origId);
10469                return;
10470            }
10471
10472            Message msg = Message.obtain();
10473            msg.what = SHOW_ERROR_MSG;
10474            HashMap data = new HashMap();
10475            data.put("result", result);
10476            data.put("app", r);
10477            msg.obj = data;
10478            mHandler.sendMessage(msg);
10479
10480            Binder.restoreCallingIdentity(origId);
10481        }
10482
10483        int res = result.get();
10484
10485        Intent appErrorIntent = null;
10486        synchronized (this) {
10487            if (r != null && !r.isolated) {
10488                // XXX Can't keep track of crash time for isolated processes,
10489                // since they don't have a persistent identity.
10490                mProcessCrashTimes.put(r.info.processName, r.uid,
10491                        SystemClock.uptimeMillis());
10492            }
10493            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10494                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10495            }
10496        }
10497
10498        if (appErrorIntent != null) {
10499            try {
10500                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10501            } catch (ActivityNotFoundException e) {
10502                Slog.w(TAG, "bug report receiver dissappeared", e);
10503            }
10504        }
10505    }
10506
10507    Intent createAppErrorIntentLocked(ProcessRecord r,
10508            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10509        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10510        if (report == null) {
10511            return null;
10512        }
10513        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10514        result.setComponent(r.errorReportReceiver);
10515        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10516        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10517        return result;
10518    }
10519
10520    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10521            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10522        if (r.errorReportReceiver == null) {
10523            return null;
10524        }
10525
10526        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10527            return null;
10528        }
10529
10530        ApplicationErrorReport report = new ApplicationErrorReport();
10531        report.packageName = r.info.packageName;
10532        report.installerPackageName = r.errorReportReceiver.getPackageName();
10533        report.processName = r.processName;
10534        report.time = timeMillis;
10535        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10536
10537        if (r.crashing || r.forceCrashReport) {
10538            report.type = ApplicationErrorReport.TYPE_CRASH;
10539            report.crashInfo = crashInfo;
10540        } else if (r.notResponding) {
10541            report.type = ApplicationErrorReport.TYPE_ANR;
10542            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10543
10544            report.anrInfo.activity = r.notRespondingReport.tag;
10545            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10546            report.anrInfo.info = r.notRespondingReport.longMsg;
10547        }
10548
10549        return report;
10550    }
10551
10552    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10553        enforceNotIsolatedCaller("getProcessesInErrorState");
10554        // assume our apps are happy - lazy create the list
10555        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10556
10557        final boolean allUsers = ActivityManager.checkUidPermission(
10558                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10559                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10560        int userId = UserHandle.getUserId(Binder.getCallingUid());
10561
10562        synchronized (this) {
10563
10564            // iterate across all processes
10565            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10566                ProcessRecord app = mLruProcesses.get(i);
10567                if (!allUsers && app.userId != userId) {
10568                    continue;
10569                }
10570                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10571                    // This one's in trouble, so we'll generate a report for it
10572                    // crashes are higher priority (in case there's a crash *and* an anr)
10573                    ActivityManager.ProcessErrorStateInfo report = null;
10574                    if (app.crashing) {
10575                        report = app.crashingReport;
10576                    } else if (app.notResponding) {
10577                        report = app.notRespondingReport;
10578                    }
10579
10580                    if (report != null) {
10581                        if (errList == null) {
10582                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10583                        }
10584                        errList.add(report);
10585                    } else {
10586                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10587                                " crashing = " + app.crashing +
10588                                " notResponding = " + app.notResponding);
10589                    }
10590                }
10591            }
10592        }
10593
10594        return errList;
10595    }
10596
10597    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10598        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10599            if (currApp != null) {
10600                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10601            }
10602            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10603        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10604            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10605        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10606            if (currApp != null) {
10607                currApp.lru = 0;
10608            }
10609            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10610        } else if (adj >= ProcessList.SERVICE_ADJ) {
10611            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10612        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10613            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10614        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10615            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10616        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10617            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10618        } else {
10619            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10620        }
10621    }
10622
10623    private void fillInProcMemInfo(ProcessRecord app,
10624            ActivityManager.RunningAppProcessInfo outInfo) {
10625        outInfo.pid = app.pid;
10626        outInfo.uid = app.info.uid;
10627        if (mHeavyWeightProcess == app) {
10628            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10629        }
10630        if (app.persistent) {
10631            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10632        }
10633        if (app.activities.size() > 0) {
10634            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10635        }
10636        outInfo.lastTrimLevel = app.trimMemoryLevel;
10637        int adj = app.curAdj;
10638        outInfo.importance = oomAdjToImportance(adj, outInfo);
10639        outInfo.importanceReasonCode = app.adjTypeCode;
10640        outInfo.processState = app.curProcState;
10641    }
10642
10643    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10644        enforceNotIsolatedCaller("getRunningAppProcesses");
10645        // Lazy instantiation of list
10646        List<ActivityManager.RunningAppProcessInfo> runList = null;
10647        final boolean allUsers = ActivityManager.checkUidPermission(
10648                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10649                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10650        int userId = UserHandle.getUserId(Binder.getCallingUid());
10651        synchronized (this) {
10652            // Iterate across all processes
10653            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10654                ProcessRecord app = mLruProcesses.get(i);
10655                if (!allUsers && app.userId != userId) {
10656                    continue;
10657                }
10658                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10659                    // Generate process state info for running application
10660                    ActivityManager.RunningAppProcessInfo currApp =
10661                        new ActivityManager.RunningAppProcessInfo(app.processName,
10662                                app.pid, app.getPackageList());
10663                    fillInProcMemInfo(app, currApp);
10664                    if (app.adjSource instanceof ProcessRecord) {
10665                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10666                        currApp.importanceReasonImportance = oomAdjToImportance(
10667                                app.adjSourceOom, null);
10668                    } else if (app.adjSource instanceof ActivityRecord) {
10669                        ActivityRecord r = (ActivityRecord)app.adjSource;
10670                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10671                    }
10672                    if (app.adjTarget instanceof ComponentName) {
10673                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10674                    }
10675                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10676                    //        + " lru=" + currApp.lru);
10677                    if (runList == null) {
10678                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10679                    }
10680                    runList.add(currApp);
10681                }
10682            }
10683        }
10684        return runList;
10685    }
10686
10687    public List<ApplicationInfo> getRunningExternalApplications() {
10688        enforceNotIsolatedCaller("getRunningExternalApplications");
10689        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10690        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10691        if (runningApps != null && runningApps.size() > 0) {
10692            Set<String> extList = new HashSet<String>();
10693            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10694                if (app.pkgList != null) {
10695                    for (String pkg : app.pkgList) {
10696                        extList.add(pkg);
10697                    }
10698                }
10699            }
10700            IPackageManager pm = AppGlobals.getPackageManager();
10701            for (String pkg : extList) {
10702                try {
10703                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10704                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10705                        retList.add(info);
10706                    }
10707                } catch (RemoteException e) {
10708                }
10709            }
10710        }
10711        return retList;
10712    }
10713
10714    @Override
10715    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10716        enforceNotIsolatedCaller("getMyMemoryState");
10717        synchronized (this) {
10718            ProcessRecord proc;
10719            synchronized (mPidsSelfLocked) {
10720                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10721            }
10722            fillInProcMemInfo(proc, outInfo);
10723        }
10724    }
10725
10726    @Override
10727    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10728        if (checkCallingPermission(android.Manifest.permission.DUMP)
10729                != PackageManager.PERMISSION_GRANTED) {
10730            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10731                    + Binder.getCallingPid()
10732                    + ", uid=" + Binder.getCallingUid()
10733                    + " without permission "
10734                    + android.Manifest.permission.DUMP);
10735            return;
10736        }
10737
10738        boolean dumpAll = false;
10739        boolean dumpClient = false;
10740        String dumpPackage = null;
10741
10742        int opti = 0;
10743        while (opti < args.length) {
10744            String opt = args[opti];
10745            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10746                break;
10747            }
10748            opti++;
10749            if ("-a".equals(opt)) {
10750                dumpAll = true;
10751            } else if ("-c".equals(opt)) {
10752                dumpClient = true;
10753            } else if ("-h".equals(opt)) {
10754                pw.println("Activity manager dump options:");
10755                pw.println("  [-a] [-c] [-h] [cmd] ...");
10756                pw.println("  cmd may be one of:");
10757                pw.println("    a[ctivities]: activity stack state");
10758                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10759                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10760                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10761                pw.println("    o[om]: out of memory management");
10762                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10763                pw.println("    provider [COMP_SPEC]: provider client-side state");
10764                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10765                pw.println("    service [COMP_SPEC]: service client-side state");
10766                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10767                pw.println("    all: dump all activities");
10768                pw.println("    top: dump the top activity");
10769                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10770                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10771                pw.println("    a partial substring in a component name, a");
10772                pw.println("    hex object identifier.");
10773                pw.println("  -a: include all available server state.");
10774                pw.println("  -c: include client state.");
10775                return;
10776            } else {
10777                pw.println("Unknown argument: " + opt + "; use -h for help");
10778            }
10779        }
10780
10781        long origId = Binder.clearCallingIdentity();
10782        boolean more = false;
10783        // Is the caller requesting to dump a particular piece of data?
10784        if (opti < args.length) {
10785            String cmd = args[opti];
10786            opti++;
10787            if ("activities".equals(cmd) || "a".equals(cmd)) {
10788                synchronized (this) {
10789                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10790                }
10791            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10792                String[] newArgs;
10793                String name;
10794                if (opti >= args.length) {
10795                    name = null;
10796                    newArgs = EMPTY_STRING_ARRAY;
10797                } else {
10798                    name = args[opti];
10799                    opti++;
10800                    newArgs = new String[args.length - opti];
10801                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10802                            args.length - opti);
10803                }
10804                synchronized (this) {
10805                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10806                }
10807            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10808                String[] newArgs;
10809                String name;
10810                if (opti >= args.length) {
10811                    name = null;
10812                    newArgs = EMPTY_STRING_ARRAY;
10813                } else {
10814                    name = args[opti];
10815                    opti++;
10816                    newArgs = new String[args.length - opti];
10817                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10818                            args.length - opti);
10819                }
10820                synchronized (this) {
10821                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10822                }
10823            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10824                String[] newArgs;
10825                String name;
10826                if (opti >= args.length) {
10827                    name = null;
10828                    newArgs = EMPTY_STRING_ARRAY;
10829                } else {
10830                    name = args[opti];
10831                    opti++;
10832                    newArgs = new String[args.length - opti];
10833                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10834                            args.length - opti);
10835                }
10836                synchronized (this) {
10837                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10838                }
10839            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10840                synchronized (this) {
10841                    dumpOomLocked(fd, pw, args, opti, true);
10842                }
10843            } else if ("provider".equals(cmd)) {
10844                String[] newArgs;
10845                String name;
10846                if (opti >= args.length) {
10847                    name = null;
10848                    newArgs = EMPTY_STRING_ARRAY;
10849                } else {
10850                    name = args[opti];
10851                    opti++;
10852                    newArgs = new String[args.length - opti];
10853                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10854                }
10855                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10856                    pw.println("No providers match: " + name);
10857                    pw.println("Use -h for help.");
10858                }
10859            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10860                synchronized (this) {
10861                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10862                }
10863            } else if ("service".equals(cmd)) {
10864                String[] newArgs;
10865                String name;
10866                if (opti >= args.length) {
10867                    name = null;
10868                    newArgs = EMPTY_STRING_ARRAY;
10869                } else {
10870                    name = args[opti];
10871                    opti++;
10872                    newArgs = new String[args.length - opti];
10873                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10874                            args.length - opti);
10875                }
10876                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10877                    pw.println("No services match: " + name);
10878                    pw.println("Use -h for help.");
10879                }
10880            } else if ("package".equals(cmd)) {
10881                String[] newArgs;
10882                if (opti >= args.length) {
10883                    pw.println("package: no package name specified");
10884                    pw.println("Use -h for help.");
10885                } else {
10886                    dumpPackage = args[opti];
10887                    opti++;
10888                    newArgs = new String[args.length - opti];
10889                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10890                            args.length - opti);
10891                    args = newArgs;
10892                    opti = 0;
10893                    more = true;
10894                }
10895            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10896                synchronized (this) {
10897                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10898                }
10899            } else {
10900                // Dumping a single activity?
10901                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10902                    pw.println("Bad activity command, or no activities match: " + cmd);
10903                    pw.println("Use -h for help.");
10904                }
10905            }
10906            if (!more) {
10907                Binder.restoreCallingIdentity(origId);
10908                return;
10909            }
10910        }
10911
10912        // No piece of data specified, dump everything.
10913        synchronized (this) {
10914            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10915            pw.println();
10916            if (dumpAll) {
10917                pw.println("-------------------------------------------------------------------------------");
10918            }
10919            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10920            pw.println();
10921            if (dumpAll) {
10922                pw.println("-------------------------------------------------------------------------------");
10923            }
10924            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10925            pw.println();
10926            if (dumpAll) {
10927                pw.println("-------------------------------------------------------------------------------");
10928            }
10929            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10930            pw.println();
10931            if (dumpAll) {
10932                pw.println("-------------------------------------------------------------------------------");
10933            }
10934            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10935            pw.println();
10936            if (dumpAll) {
10937                pw.println("-------------------------------------------------------------------------------");
10938            }
10939            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10940        }
10941        Binder.restoreCallingIdentity(origId);
10942    }
10943
10944    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10945            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10946        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10947
10948        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10949                dumpPackage);
10950        boolean needSep = printedAnything;
10951
10952        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10953                dumpPackage, needSep, "  mFocusedActivity: ");
10954        if (printed) {
10955            printedAnything = true;
10956            needSep = false;
10957        }
10958
10959        if (dumpPackage == null) {
10960            if (needSep) {
10961                pw.println();
10962            }
10963            needSep = true;
10964            printedAnything = true;
10965            mStackSupervisor.dump(pw, "  ");
10966        }
10967
10968        if (mRecentTasks.size() > 0) {
10969            boolean printedHeader = false;
10970
10971            final int N = mRecentTasks.size();
10972            for (int i=0; i<N; i++) {
10973                TaskRecord tr = mRecentTasks.get(i);
10974                if (dumpPackage != null) {
10975                    if (tr.realActivity == null ||
10976                            !dumpPackage.equals(tr.realActivity)) {
10977                        continue;
10978                    }
10979                }
10980                if (!printedHeader) {
10981                    if (needSep) {
10982                        pw.println();
10983                    }
10984                    pw.println("  Recent tasks:");
10985                    printedHeader = true;
10986                    printedAnything = true;
10987                }
10988                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10989                        pw.println(tr);
10990                if (dumpAll) {
10991                    mRecentTasks.get(i).dump(pw, "    ");
10992                }
10993            }
10994        }
10995
10996        if (!printedAnything) {
10997            pw.println("  (nothing)");
10998        }
10999    }
11000
11001    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11002            int opti, boolean dumpAll, String dumpPackage) {
11003        boolean needSep = false;
11004        boolean printedAnything = false;
11005        int numPers = 0;
11006
11007        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11008
11009        if (dumpAll) {
11010            final int NP = mProcessNames.getMap().size();
11011            for (int ip=0; ip<NP; ip++) {
11012                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11013                final int NA = procs.size();
11014                for (int ia=0; ia<NA; ia++) {
11015                    ProcessRecord r = procs.valueAt(ia);
11016                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11017                        continue;
11018                    }
11019                    if (!needSep) {
11020                        pw.println("  All known processes:");
11021                        needSep = true;
11022                        printedAnything = true;
11023                    }
11024                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11025                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11026                        pw.print(" "); pw.println(r);
11027                    r.dump(pw, "    ");
11028                    if (r.persistent) {
11029                        numPers++;
11030                    }
11031                }
11032            }
11033        }
11034
11035        if (mIsolatedProcesses.size() > 0) {
11036            boolean printed = false;
11037            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11038                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11039                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11040                    continue;
11041                }
11042                if (!printed) {
11043                    if (needSep) {
11044                        pw.println();
11045                    }
11046                    pw.println("  Isolated process list (sorted by uid):");
11047                    printedAnything = true;
11048                    printed = true;
11049                    needSep = true;
11050                }
11051                pw.println(String.format("%sIsolated #%2d: %s",
11052                        "    ", i, r.toString()));
11053            }
11054        }
11055
11056        if (mLruProcesses.size() > 0) {
11057            if (needSep) {
11058                pw.println();
11059            }
11060            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11061                    pw.print(" total, non-act at ");
11062                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11063                    pw.print(", non-svc at ");
11064                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11065                    pw.println("):");
11066            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11067            needSep = true;
11068            printedAnything = true;
11069        }
11070
11071        if (dumpAll || dumpPackage != null) {
11072            synchronized (mPidsSelfLocked) {
11073                boolean printed = false;
11074                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11075                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11076                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11077                        continue;
11078                    }
11079                    if (!printed) {
11080                        if (needSep) pw.println();
11081                        needSep = true;
11082                        pw.println("  PID mappings:");
11083                        printed = true;
11084                        printedAnything = true;
11085                    }
11086                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11087                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11088                }
11089            }
11090        }
11091
11092        if (mForegroundProcesses.size() > 0) {
11093            synchronized (mPidsSelfLocked) {
11094                boolean printed = false;
11095                for (int i=0; i<mForegroundProcesses.size(); i++) {
11096                    ProcessRecord r = mPidsSelfLocked.get(
11097                            mForegroundProcesses.valueAt(i).pid);
11098                    if (dumpPackage != null && (r == null
11099                            || !r.pkgList.containsKey(dumpPackage))) {
11100                        continue;
11101                    }
11102                    if (!printed) {
11103                        if (needSep) pw.println();
11104                        needSep = true;
11105                        pw.println("  Foreground Processes:");
11106                        printed = true;
11107                        printedAnything = true;
11108                    }
11109                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11110                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11111                }
11112            }
11113        }
11114
11115        if (mPersistentStartingProcesses.size() > 0) {
11116            if (needSep) pw.println();
11117            needSep = true;
11118            printedAnything = true;
11119            pw.println("  Persisent processes that are starting:");
11120            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11121                    "Starting Norm", "Restarting PERS", dumpPackage);
11122        }
11123
11124        if (mRemovedProcesses.size() > 0) {
11125            if (needSep) pw.println();
11126            needSep = true;
11127            printedAnything = true;
11128            pw.println("  Processes that are being removed:");
11129            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11130                    "Removed Norm", "Removed PERS", dumpPackage);
11131        }
11132
11133        if (mProcessesOnHold.size() > 0) {
11134            if (needSep) pw.println();
11135            needSep = true;
11136            printedAnything = true;
11137            pw.println("  Processes that are on old until the system is ready:");
11138            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11139                    "OnHold Norm", "OnHold PERS", dumpPackage);
11140        }
11141
11142        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11143
11144        if (mProcessCrashTimes.getMap().size() > 0) {
11145            boolean printed = false;
11146            long now = SystemClock.uptimeMillis();
11147            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11148            final int NP = pmap.size();
11149            for (int ip=0; ip<NP; ip++) {
11150                String pname = pmap.keyAt(ip);
11151                SparseArray<Long> uids = pmap.valueAt(ip);
11152                final int N = uids.size();
11153                for (int i=0; i<N; i++) {
11154                    int puid = uids.keyAt(i);
11155                    ProcessRecord r = mProcessNames.get(pname, puid);
11156                    if (dumpPackage != null && (r == null
11157                            || !r.pkgList.containsKey(dumpPackage))) {
11158                        continue;
11159                    }
11160                    if (!printed) {
11161                        if (needSep) pw.println();
11162                        needSep = true;
11163                        pw.println("  Time since processes crashed:");
11164                        printed = true;
11165                        printedAnything = true;
11166                    }
11167                    pw.print("    Process "); pw.print(pname);
11168                            pw.print(" uid "); pw.print(puid);
11169                            pw.print(": last crashed ");
11170                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11171                            pw.println(" ago");
11172                }
11173            }
11174        }
11175
11176        if (mBadProcesses.getMap().size() > 0) {
11177            boolean printed = false;
11178            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11179            final int NP = pmap.size();
11180            for (int ip=0; ip<NP; ip++) {
11181                String pname = pmap.keyAt(ip);
11182                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11183                final int N = uids.size();
11184                for (int i=0; i<N; i++) {
11185                    int puid = uids.keyAt(i);
11186                    ProcessRecord r = mProcessNames.get(pname, puid);
11187                    if (dumpPackage != null && (r == null
11188                            || !r.pkgList.containsKey(dumpPackage))) {
11189                        continue;
11190                    }
11191                    if (!printed) {
11192                        if (needSep) pw.println();
11193                        needSep = true;
11194                        pw.println("  Bad processes:");
11195                        printedAnything = true;
11196                    }
11197                    BadProcessInfo info = uids.valueAt(i);
11198                    pw.print("    Bad process "); pw.print(pname);
11199                            pw.print(" uid "); pw.print(puid);
11200                            pw.print(": crashed at time "); pw.println(info.time);
11201                    if (info.shortMsg != null) {
11202                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11203                    }
11204                    if (info.longMsg != null) {
11205                        pw.print("      Long msg: "); pw.println(info.longMsg);
11206                    }
11207                    if (info.stack != null) {
11208                        pw.println("      Stack:");
11209                        int lastPos = 0;
11210                        for (int pos=0; pos<info.stack.length(); pos++) {
11211                            if (info.stack.charAt(pos) == '\n') {
11212                                pw.print("        ");
11213                                pw.write(info.stack, lastPos, pos-lastPos);
11214                                pw.println();
11215                                lastPos = pos+1;
11216                            }
11217                        }
11218                        if (lastPos < info.stack.length()) {
11219                            pw.print("        ");
11220                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11221                            pw.println();
11222                        }
11223                    }
11224                }
11225            }
11226        }
11227
11228        if (dumpPackage == null) {
11229            pw.println();
11230            needSep = false;
11231            pw.println("  mStartedUsers:");
11232            for (int i=0; i<mStartedUsers.size(); i++) {
11233                UserStartedState uss = mStartedUsers.valueAt(i);
11234                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11235                        pw.print(": "); uss.dump("", pw);
11236            }
11237            pw.print("  mStartedUserArray: [");
11238            for (int i=0; i<mStartedUserArray.length; i++) {
11239                if (i > 0) pw.print(", ");
11240                pw.print(mStartedUserArray[i]);
11241            }
11242            pw.println("]");
11243            pw.print("  mUserLru: [");
11244            for (int i=0; i<mUserLru.size(); i++) {
11245                if (i > 0) pw.print(", ");
11246                pw.print(mUserLru.get(i));
11247            }
11248            pw.println("]");
11249            if (dumpAll) {
11250                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11251            }
11252        }
11253        if (mHomeProcess != null && (dumpPackage == null
11254                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11255            if (needSep) {
11256                pw.println();
11257                needSep = false;
11258            }
11259            pw.println("  mHomeProcess: " + mHomeProcess);
11260        }
11261        if (mPreviousProcess != null && (dumpPackage == null
11262                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11263            if (needSep) {
11264                pw.println();
11265                needSep = false;
11266            }
11267            pw.println("  mPreviousProcess: " + mPreviousProcess);
11268        }
11269        if (dumpAll) {
11270            StringBuilder sb = new StringBuilder(128);
11271            sb.append("  mPreviousProcessVisibleTime: ");
11272            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11273            pw.println(sb);
11274        }
11275        if (mHeavyWeightProcess != null && (dumpPackage == null
11276                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11277            if (needSep) {
11278                pw.println();
11279                needSep = false;
11280            }
11281            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11282        }
11283        if (dumpPackage == null) {
11284            pw.println("  mConfiguration: " + mConfiguration);
11285        }
11286        if (dumpAll) {
11287            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11288            if (mCompatModePackages.getPackages().size() > 0) {
11289                boolean printed = false;
11290                for (Map.Entry<String, Integer> entry
11291                        : mCompatModePackages.getPackages().entrySet()) {
11292                    String pkg = entry.getKey();
11293                    int mode = entry.getValue();
11294                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11295                        continue;
11296                    }
11297                    if (!printed) {
11298                        pw.println("  mScreenCompatPackages:");
11299                        printed = true;
11300                    }
11301                    pw.print("    "); pw.print(pkg); pw.print(": ");
11302                            pw.print(mode); pw.println();
11303                }
11304            }
11305        }
11306        if (dumpPackage == null) {
11307            if (mSleeping || mWentToSleep || mLockScreenShown) {
11308                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11309                        + " mLockScreenShown " + mLockScreenShown);
11310            }
11311            if (mShuttingDown || mRunningVoice) {
11312                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11313            }
11314        }
11315        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11316                || mOrigWaitForDebugger) {
11317            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11318                    || dumpPackage.equals(mOrigDebugApp)) {
11319                if (needSep) {
11320                    pw.println();
11321                    needSep = false;
11322                }
11323                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11324                        + " mDebugTransient=" + mDebugTransient
11325                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11326            }
11327        }
11328        if (mOpenGlTraceApp != null) {
11329            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11330                if (needSep) {
11331                    pw.println();
11332                    needSep = false;
11333                }
11334                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11335            }
11336        }
11337        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11338                || mProfileFd != null) {
11339            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11340                if (needSep) {
11341                    pw.println();
11342                    needSep = false;
11343                }
11344                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11345                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11346                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11347                        + mAutoStopProfiler);
11348            }
11349        }
11350        if (dumpPackage == null) {
11351            if (mAlwaysFinishActivities || mController != null) {
11352                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11353                        + " mController=" + mController);
11354            }
11355            if (dumpAll) {
11356                pw.println("  Total persistent processes: " + numPers);
11357                pw.println("  mProcessesReady=" + mProcessesReady
11358                        + " mSystemReady=" + mSystemReady);
11359                pw.println("  mBooting=" + mBooting
11360                        + " mBooted=" + mBooted
11361                        + " mFactoryTest=" + mFactoryTest);
11362                pw.print("  mLastPowerCheckRealtime=");
11363                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11364                        pw.println("");
11365                pw.print("  mLastPowerCheckUptime=");
11366                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11367                        pw.println("");
11368                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11369                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11370                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11371                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11372                        + " (" + mLruProcesses.size() + " total)"
11373                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11374                        + " mNumServiceProcs=" + mNumServiceProcs
11375                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11376                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11377                        + " mLastMemoryLevel" + mLastMemoryLevel
11378                        + " mLastNumProcesses" + mLastNumProcesses);
11379                long now = SystemClock.uptimeMillis();
11380                pw.print("  mLastIdleTime=");
11381                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11382                        pw.print(" mLowRamSinceLastIdle=");
11383                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11384                        pw.println();
11385            }
11386        }
11387
11388        if (!printedAnything) {
11389            pw.println("  (nothing)");
11390        }
11391    }
11392
11393    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11394            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11395        if (mProcessesToGc.size() > 0) {
11396            boolean printed = false;
11397            long now = SystemClock.uptimeMillis();
11398            for (int i=0; i<mProcessesToGc.size(); i++) {
11399                ProcessRecord proc = mProcessesToGc.get(i);
11400                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11401                    continue;
11402                }
11403                if (!printed) {
11404                    if (needSep) pw.println();
11405                    needSep = true;
11406                    pw.println("  Processes that are waiting to GC:");
11407                    printed = true;
11408                }
11409                pw.print("    Process "); pw.println(proc);
11410                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11411                        pw.print(", last gced=");
11412                        pw.print(now-proc.lastRequestedGc);
11413                        pw.print(" ms ago, last lowMem=");
11414                        pw.print(now-proc.lastLowMemory);
11415                        pw.println(" ms ago");
11416
11417            }
11418        }
11419        return needSep;
11420    }
11421
11422    void printOomLevel(PrintWriter pw, String name, int adj) {
11423        pw.print("    ");
11424        if (adj >= 0) {
11425            pw.print(' ');
11426            if (adj < 10) pw.print(' ');
11427        } else {
11428            if (adj > -10) pw.print(' ');
11429        }
11430        pw.print(adj);
11431        pw.print(": ");
11432        pw.print(name);
11433        pw.print(" (");
11434        pw.print(mProcessList.getMemLevel(adj)/1024);
11435        pw.println(" kB)");
11436    }
11437
11438    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11439            int opti, boolean dumpAll) {
11440        boolean needSep = false;
11441
11442        if (mLruProcesses.size() > 0) {
11443            if (needSep) pw.println();
11444            needSep = true;
11445            pw.println("  OOM levels:");
11446            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11447            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11448            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11449            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11450            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11451            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11452            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11453            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11454            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11455            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11456            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11457            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11458            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11459
11460            if (needSep) pw.println();
11461            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11462                    pw.print(" total, non-act at ");
11463                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11464                    pw.print(", non-svc at ");
11465                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11466                    pw.println("):");
11467            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11468            needSep = true;
11469        }
11470
11471        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11472
11473        pw.println();
11474        pw.println("  mHomeProcess: " + mHomeProcess);
11475        pw.println("  mPreviousProcess: " + mPreviousProcess);
11476        if (mHeavyWeightProcess != null) {
11477            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11478        }
11479
11480        return true;
11481    }
11482
11483    /**
11484     * There are three ways to call this:
11485     *  - no provider specified: dump all the providers
11486     *  - a flattened component name that matched an existing provider was specified as the
11487     *    first arg: dump that one provider
11488     *  - the first arg isn't the flattened component name of an existing provider:
11489     *    dump all providers whose component contains the first arg as a substring
11490     */
11491    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11492            int opti, boolean dumpAll) {
11493        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11494    }
11495
11496    static class ItemMatcher {
11497        ArrayList<ComponentName> components;
11498        ArrayList<String> strings;
11499        ArrayList<Integer> objects;
11500        boolean all;
11501
11502        ItemMatcher() {
11503            all = true;
11504        }
11505
11506        void build(String name) {
11507            ComponentName componentName = ComponentName.unflattenFromString(name);
11508            if (componentName != null) {
11509                if (components == null) {
11510                    components = new ArrayList<ComponentName>();
11511                }
11512                components.add(componentName);
11513                all = false;
11514            } else {
11515                int objectId = 0;
11516                // Not a '/' separated full component name; maybe an object ID?
11517                try {
11518                    objectId = Integer.parseInt(name, 16);
11519                    if (objects == null) {
11520                        objects = new ArrayList<Integer>();
11521                    }
11522                    objects.add(objectId);
11523                    all = false;
11524                } catch (RuntimeException e) {
11525                    // Not an integer; just do string match.
11526                    if (strings == null) {
11527                        strings = new ArrayList<String>();
11528                    }
11529                    strings.add(name);
11530                    all = false;
11531                }
11532            }
11533        }
11534
11535        int build(String[] args, int opti) {
11536            for (; opti<args.length; opti++) {
11537                String name = args[opti];
11538                if ("--".equals(name)) {
11539                    return opti+1;
11540                }
11541                build(name);
11542            }
11543            return opti;
11544        }
11545
11546        boolean match(Object object, ComponentName comp) {
11547            if (all) {
11548                return true;
11549            }
11550            if (components != null) {
11551                for (int i=0; i<components.size(); i++) {
11552                    if (components.get(i).equals(comp)) {
11553                        return true;
11554                    }
11555                }
11556            }
11557            if (objects != null) {
11558                for (int i=0; i<objects.size(); i++) {
11559                    if (System.identityHashCode(object) == objects.get(i)) {
11560                        return true;
11561                    }
11562                }
11563            }
11564            if (strings != null) {
11565                String flat = comp.flattenToString();
11566                for (int i=0; i<strings.size(); i++) {
11567                    if (flat.contains(strings.get(i))) {
11568                        return true;
11569                    }
11570                }
11571            }
11572            return false;
11573        }
11574    }
11575
11576    /**
11577     * There are three things that cmd can be:
11578     *  - a flattened component name that matches an existing activity
11579     *  - the cmd arg isn't the flattened component name of an existing activity:
11580     *    dump all activity whose component contains the cmd as a substring
11581     *  - A hex number of the ActivityRecord object instance.
11582     */
11583    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11584            int opti, boolean dumpAll) {
11585        ArrayList<ActivityRecord> activities;
11586
11587        synchronized (this) {
11588            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11589        }
11590
11591        if (activities.size() <= 0) {
11592            return false;
11593        }
11594
11595        String[] newArgs = new String[args.length - opti];
11596        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11597
11598        TaskRecord lastTask = null;
11599        boolean needSep = false;
11600        for (int i=activities.size()-1; i>=0; i--) {
11601            ActivityRecord r = activities.get(i);
11602            if (needSep) {
11603                pw.println();
11604            }
11605            needSep = true;
11606            synchronized (this) {
11607                if (lastTask != r.task) {
11608                    lastTask = r.task;
11609                    pw.print("TASK "); pw.print(lastTask.affinity);
11610                            pw.print(" id="); pw.println(lastTask.taskId);
11611                    if (dumpAll) {
11612                        lastTask.dump(pw, "  ");
11613                    }
11614                }
11615            }
11616            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11617        }
11618        return true;
11619    }
11620
11621    /**
11622     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11623     * there is a thread associated with the activity.
11624     */
11625    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11626            final ActivityRecord r, String[] args, boolean dumpAll) {
11627        String innerPrefix = prefix + "  ";
11628        synchronized (this) {
11629            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11630                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11631                    pw.print(" pid=");
11632                    if (r.app != null) pw.println(r.app.pid);
11633                    else pw.println("(not running)");
11634            if (dumpAll) {
11635                r.dump(pw, innerPrefix);
11636            }
11637        }
11638        if (r.app != null && r.app.thread != null) {
11639            // flush anything that is already in the PrintWriter since the thread is going
11640            // to write to the file descriptor directly
11641            pw.flush();
11642            try {
11643                TransferPipe tp = new TransferPipe();
11644                try {
11645                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11646                            r.appToken, innerPrefix, args);
11647                    tp.go(fd);
11648                } finally {
11649                    tp.kill();
11650                }
11651            } catch (IOException e) {
11652                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11653            } catch (RemoteException e) {
11654                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11655            }
11656        }
11657    }
11658
11659    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11660            int opti, boolean dumpAll, String dumpPackage) {
11661        boolean needSep = false;
11662        boolean onlyHistory = false;
11663        boolean printedAnything = false;
11664
11665        if ("history".equals(dumpPackage)) {
11666            if (opti < args.length && "-s".equals(args[opti])) {
11667                dumpAll = false;
11668            }
11669            onlyHistory = true;
11670            dumpPackage = null;
11671        }
11672
11673        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11674        if (!onlyHistory && dumpAll) {
11675            if (mRegisteredReceivers.size() > 0) {
11676                boolean printed = false;
11677                Iterator it = mRegisteredReceivers.values().iterator();
11678                while (it.hasNext()) {
11679                    ReceiverList r = (ReceiverList)it.next();
11680                    if (dumpPackage != null && (r.app == null ||
11681                            !dumpPackage.equals(r.app.info.packageName))) {
11682                        continue;
11683                    }
11684                    if (!printed) {
11685                        pw.println("  Registered Receivers:");
11686                        needSep = true;
11687                        printed = true;
11688                        printedAnything = true;
11689                    }
11690                    pw.print("  * "); pw.println(r);
11691                    r.dump(pw, "    ");
11692                }
11693            }
11694
11695            if (mReceiverResolver.dump(pw, needSep ?
11696                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11697                    "    ", dumpPackage, false)) {
11698                needSep = true;
11699                printedAnything = true;
11700            }
11701        }
11702
11703        for (BroadcastQueue q : mBroadcastQueues) {
11704            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11705            printedAnything |= needSep;
11706        }
11707
11708        needSep = true;
11709
11710        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11711            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11712                if (needSep) {
11713                    pw.println();
11714                }
11715                needSep = true;
11716                printedAnything = true;
11717                pw.print("  Sticky broadcasts for user ");
11718                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11719                StringBuilder sb = new StringBuilder(128);
11720                for (Map.Entry<String, ArrayList<Intent>> ent
11721                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11722                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11723                    if (dumpAll) {
11724                        pw.println(":");
11725                        ArrayList<Intent> intents = ent.getValue();
11726                        final int N = intents.size();
11727                        for (int i=0; i<N; i++) {
11728                            sb.setLength(0);
11729                            sb.append("    Intent: ");
11730                            intents.get(i).toShortString(sb, false, true, false, false);
11731                            pw.println(sb.toString());
11732                            Bundle bundle = intents.get(i).getExtras();
11733                            if (bundle != null) {
11734                                pw.print("      ");
11735                                pw.println(bundle.toString());
11736                            }
11737                        }
11738                    } else {
11739                        pw.println("");
11740                    }
11741                }
11742            }
11743        }
11744
11745        if (!onlyHistory && dumpAll) {
11746            pw.println();
11747            for (BroadcastQueue queue : mBroadcastQueues) {
11748                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11749                        + queue.mBroadcastsScheduled);
11750            }
11751            pw.println("  mHandler:");
11752            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11753            needSep = true;
11754            printedAnything = true;
11755        }
11756
11757        if (!printedAnything) {
11758            pw.println("  (nothing)");
11759        }
11760    }
11761
11762    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11763            int opti, boolean dumpAll, String dumpPackage) {
11764        boolean needSep;
11765        boolean printedAnything = false;
11766
11767        ItemMatcher matcher = new ItemMatcher();
11768        matcher.build(args, opti);
11769
11770        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11771
11772        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11773        printedAnything |= needSep;
11774
11775        if (mLaunchingProviders.size() > 0) {
11776            boolean printed = false;
11777            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11778                ContentProviderRecord r = mLaunchingProviders.get(i);
11779                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11780                    continue;
11781                }
11782                if (!printed) {
11783                    if (needSep) pw.println();
11784                    needSep = true;
11785                    pw.println("  Launching content providers:");
11786                    printed = true;
11787                    printedAnything = true;
11788                }
11789                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11790                        pw.println(r);
11791            }
11792        }
11793
11794        if (mGrantedUriPermissions.size() > 0) {
11795            boolean printed = false;
11796            int dumpUid = -2;
11797            if (dumpPackage != null) {
11798                try {
11799                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11800                } catch (NameNotFoundException e) {
11801                    dumpUid = -1;
11802                }
11803            }
11804            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11805                int uid = mGrantedUriPermissions.keyAt(i);
11806                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11807                    continue;
11808                }
11809                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11810                if (!printed) {
11811                    if (needSep) pw.println();
11812                    needSep = true;
11813                    pw.println("  Granted Uri Permissions:");
11814                    printed = true;
11815                    printedAnything = true;
11816                }
11817                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11818                for (UriPermission perm : perms.values()) {
11819                    pw.print("    "); pw.println(perm);
11820                    if (dumpAll) {
11821                        perm.dump(pw, "      ");
11822                    }
11823                }
11824            }
11825        }
11826
11827        if (!printedAnything) {
11828            pw.println("  (nothing)");
11829        }
11830    }
11831
11832    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11833            int opti, boolean dumpAll, String dumpPackage) {
11834        boolean printed = false;
11835
11836        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11837
11838        if (mIntentSenderRecords.size() > 0) {
11839            Iterator<WeakReference<PendingIntentRecord>> it
11840                    = mIntentSenderRecords.values().iterator();
11841            while (it.hasNext()) {
11842                WeakReference<PendingIntentRecord> ref = it.next();
11843                PendingIntentRecord rec = ref != null ? ref.get(): null;
11844                if (dumpPackage != null && (rec == null
11845                        || !dumpPackage.equals(rec.key.packageName))) {
11846                    continue;
11847                }
11848                printed = true;
11849                if (rec != null) {
11850                    pw.print("  * "); pw.println(rec);
11851                    if (dumpAll) {
11852                        rec.dump(pw, "    ");
11853                    }
11854                } else {
11855                    pw.print("  * "); pw.println(ref);
11856                }
11857            }
11858        }
11859
11860        if (!printed) {
11861            pw.println("  (nothing)");
11862        }
11863    }
11864
11865    private static final int dumpProcessList(PrintWriter pw,
11866            ActivityManagerService service, List list,
11867            String prefix, String normalLabel, String persistentLabel,
11868            String dumpPackage) {
11869        int numPers = 0;
11870        final int N = list.size()-1;
11871        for (int i=N; i>=0; i--) {
11872            ProcessRecord r = (ProcessRecord)list.get(i);
11873            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11874                continue;
11875            }
11876            pw.println(String.format("%s%s #%2d: %s",
11877                    prefix, (r.persistent ? persistentLabel : normalLabel),
11878                    i, r.toString()));
11879            if (r.persistent) {
11880                numPers++;
11881            }
11882        }
11883        return numPers;
11884    }
11885
11886    private static final boolean dumpProcessOomList(PrintWriter pw,
11887            ActivityManagerService service, List<ProcessRecord> origList,
11888            String prefix, String normalLabel, String persistentLabel,
11889            boolean inclDetails, String dumpPackage) {
11890
11891        ArrayList<Pair<ProcessRecord, Integer>> list
11892                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11893        for (int i=0; i<origList.size(); i++) {
11894            ProcessRecord r = origList.get(i);
11895            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11896                continue;
11897            }
11898            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11899        }
11900
11901        if (list.size() <= 0) {
11902            return false;
11903        }
11904
11905        Comparator<Pair<ProcessRecord, Integer>> comparator
11906                = new Comparator<Pair<ProcessRecord, Integer>>() {
11907            @Override
11908            public int compare(Pair<ProcessRecord, Integer> object1,
11909                    Pair<ProcessRecord, Integer> object2) {
11910                if (object1.first.setAdj != object2.first.setAdj) {
11911                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11912                }
11913                if (object1.second.intValue() != object2.second.intValue()) {
11914                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11915                }
11916                return 0;
11917            }
11918        };
11919
11920        Collections.sort(list, comparator);
11921
11922        final long curRealtime = SystemClock.elapsedRealtime();
11923        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11924        final long curUptime = SystemClock.uptimeMillis();
11925        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11926
11927        for (int i=list.size()-1; i>=0; i--) {
11928            ProcessRecord r = list.get(i).first;
11929            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11930            char schedGroup;
11931            switch (r.setSchedGroup) {
11932                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11933                    schedGroup = 'B';
11934                    break;
11935                case Process.THREAD_GROUP_DEFAULT:
11936                    schedGroup = 'F';
11937                    break;
11938                default:
11939                    schedGroup = '?';
11940                    break;
11941            }
11942            char foreground;
11943            if (r.foregroundActivities) {
11944                foreground = 'A';
11945            } else if (r.foregroundServices) {
11946                foreground = 'S';
11947            } else {
11948                foreground = ' ';
11949            }
11950            String procState = ProcessList.makeProcStateString(r.curProcState);
11951            pw.print(prefix);
11952            pw.print(r.persistent ? persistentLabel : normalLabel);
11953            pw.print(" #");
11954            int num = (origList.size()-1)-list.get(i).second;
11955            if (num < 10) pw.print(' ');
11956            pw.print(num);
11957            pw.print(": ");
11958            pw.print(oomAdj);
11959            pw.print(' ');
11960            pw.print(schedGroup);
11961            pw.print('/');
11962            pw.print(foreground);
11963            pw.print('/');
11964            pw.print(procState);
11965            pw.print(" trm:");
11966            if (r.trimMemoryLevel < 10) pw.print(' ');
11967            pw.print(r.trimMemoryLevel);
11968            pw.print(' ');
11969            pw.print(r.toShortString());
11970            pw.print(" (");
11971            pw.print(r.adjType);
11972            pw.println(')');
11973            if (r.adjSource != null || r.adjTarget != null) {
11974                pw.print(prefix);
11975                pw.print("    ");
11976                if (r.adjTarget instanceof ComponentName) {
11977                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11978                } else if (r.adjTarget != null) {
11979                    pw.print(r.adjTarget.toString());
11980                } else {
11981                    pw.print("{null}");
11982                }
11983                pw.print("<=");
11984                if (r.adjSource instanceof ProcessRecord) {
11985                    pw.print("Proc{");
11986                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11987                    pw.println("}");
11988                } else if (r.adjSource != null) {
11989                    pw.println(r.adjSource.toString());
11990                } else {
11991                    pw.println("{null}");
11992                }
11993            }
11994            if (inclDetails) {
11995                pw.print(prefix);
11996                pw.print("    ");
11997                pw.print("oom: max="); pw.print(r.maxAdj);
11998                pw.print(" curRaw="); pw.print(r.curRawAdj);
11999                pw.print(" setRaw="); pw.print(r.setRawAdj);
12000                pw.print(" cur="); pw.print(r.curAdj);
12001                pw.print(" set="); pw.println(r.setAdj);
12002                pw.print(prefix);
12003                pw.print("    ");
12004                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12005                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12006                pw.print(" lastPss="); pw.print(r.lastPss);
12007                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12008                pw.print(prefix);
12009                pw.print("    ");
12010                pw.print("keeping="); pw.print(r.keeping);
12011                pw.print(" cached="); pw.print(r.cached);
12012                pw.print(" empty="); pw.print(r.empty);
12013                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12014
12015                if (!r.keeping) {
12016                    if (r.lastWakeTime != 0) {
12017                        long wtime;
12018                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12019                        synchronized (stats) {
12020                            wtime = stats.getProcessWakeTime(r.info.uid,
12021                                    r.pid, curRealtime);
12022                        }
12023                        long timeUsed = wtime - r.lastWakeTime;
12024                        pw.print(prefix);
12025                        pw.print("    ");
12026                        pw.print("keep awake over ");
12027                        TimeUtils.formatDuration(realtimeSince, pw);
12028                        pw.print(" used ");
12029                        TimeUtils.formatDuration(timeUsed, pw);
12030                        pw.print(" (");
12031                        pw.print((timeUsed*100)/realtimeSince);
12032                        pw.println("%)");
12033                    }
12034                    if (r.lastCpuTime != 0) {
12035                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12036                        pw.print(prefix);
12037                        pw.print("    ");
12038                        pw.print("run cpu over ");
12039                        TimeUtils.formatDuration(uptimeSince, pw);
12040                        pw.print(" used ");
12041                        TimeUtils.formatDuration(timeUsed, pw);
12042                        pw.print(" (");
12043                        pw.print((timeUsed*100)/uptimeSince);
12044                        pw.println("%)");
12045                    }
12046                }
12047            }
12048        }
12049        return true;
12050    }
12051
12052    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12053        ArrayList<ProcessRecord> procs;
12054        synchronized (this) {
12055            if (args != null && args.length > start
12056                    && args[start].charAt(0) != '-') {
12057                procs = new ArrayList<ProcessRecord>();
12058                int pid = -1;
12059                try {
12060                    pid = Integer.parseInt(args[start]);
12061                } catch (NumberFormatException e) {
12062                }
12063                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12064                    ProcessRecord proc = mLruProcesses.get(i);
12065                    if (proc.pid == pid) {
12066                        procs.add(proc);
12067                    } else if (proc.processName.equals(args[start])) {
12068                        procs.add(proc);
12069                    }
12070                }
12071                if (procs.size() <= 0) {
12072                    return null;
12073                }
12074            } else {
12075                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12076            }
12077        }
12078        return procs;
12079    }
12080
12081    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12082            PrintWriter pw, String[] args) {
12083        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12084        if (procs == null) {
12085            pw.println("No process found for: " + args[0]);
12086            return;
12087        }
12088
12089        long uptime = SystemClock.uptimeMillis();
12090        long realtime = SystemClock.elapsedRealtime();
12091        pw.println("Applications Graphics Acceleration Info:");
12092        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12093
12094        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12095            ProcessRecord r = procs.get(i);
12096            if (r.thread != null) {
12097                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12098                pw.flush();
12099                try {
12100                    TransferPipe tp = new TransferPipe();
12101                    try {
12102                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12103                        tp.go(fd);
12104                    } finally {
12105                        tp.kill();
12106                    }
12107                } catch (IOException e) {
12108                    pw.println("Failure while dumping the app: " + r);
12109                    pw.flush();
12110                } catch (RemoteException e) {
12111                    pw.println("Got a RemoteException while dumping the app " + r);
12112                    pw.flush();
12113                }
12114            }
12115        }
12116    }
12117
12118    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12119        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12120        if (procs == null) {
12121            pw.println("No process found for: " + args[0]);
12122            return;
12123        }
12124
12125        pw.println("Applications Database Info:");
12126
12127        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12128            ProcessRecord r = procs.get(i);
12129            if (r.thread != null) {
12130                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12131                pw.flush();
12132                try {
12133                    TransferPipe tp = new TransferPipe();
12134                    try {
12135                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12136                        tp.go(fd);
12137                    } finally {
12138                        tp.kill();
12139                    }
12140                } catch (IOException e) {
12141                    pw.println("Failure while dumping the app: " + r);
12142                    pw.flush();
12143                } catch (RemoteException e) {
12144                    pw.println("Got a RemoteException while dumping the app " + r);
12145                    pw.flush();
12146                }
12147            }
12148        }
12149    }
12150
12151    final static class MemItem {
12152        final boolean isProc;
12153        final String label;
12154        final String shortLabel;
12155        final long pss;
12156        final int id;
12157        final boolean hasActivities;
12158        ArrayList<MemItem> subitems;
12159
12160        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12161                boolean _hasActivities) {
12162            isProc = true;
12163            label = _label;
12164            shortLabel = _shortLabel;
12165            pss = _pss;
12166            id = _id;
12167            hasActivities = _hasActivities;
12168        }
12169
12170        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12171            isProc = false;
12172            label = _label;
12173            shortLabel = _shortLabel;
12174            pss = _pss;
12175            id = _id;
12176            hasActivities = false;
12177        }
12178    }
12179
12180    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12181            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12182        if (sort && !isCompact) {
12183            Collections.sort(items, new Comparator<MemItem>() {
12184                @Override
12185                public int compare(MemItem lhs, MemItem rhs) {
12186                    if (lhs.pss < rhs.pss) {
12187                        return 1;
12188                    } else if (lhs.pss > rhs.pss) {
12189                        return -1;
12190                    }
12191                    return 0;
12192                }
12193            });
12194        }
12195
12196        for (int i=0; i<items.size(); i++) {
12197            MemItem mi = items.get(i);
12198            if (!isCompact) {
12199                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12200            } else if (mi.isProc) {
12201                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12202                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12203                pw.println(mi.hasActivities ? ",a" : ",e");
12204            } else {
12205                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12206                pw.println(mi.pss);
12207            }
12208            if (mi.subitems != null) {
12209                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12210                        true, isCompact);
12211            }
12212        }
12213    }
12214
12215    // These are in KB.
12216    static final long[] DUMP_MEM_BUCKETS = new long[] {
12217        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12218        120*1024, 160*1024, 200*1024,
12219        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12220        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12221    };
12222
12223    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12224            boolean stackLike) {
12225        int start = label.lastIndexOf('.');
12226        if (start >= 0) start++;
12227        else start = 0;
12228        int end = label.length();
12229        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12230            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12231                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12232                out.append(bucket);
12233                out.append(stackLike ? "MB." : "MB ");
12234                out.append(label, start, end);
12235                return;
12236            }
12237        }
12238        out.append(memKB/1024);
12239        out.append(stackLike ? "MB." : "MB ");
12240        out.append(label, start, end);
12241    }
12242
12243    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12244            ProcessList.NATIVE_ADJ,
12245            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12246            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12247            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12248            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12249            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12250    };
12251    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12252            "Native",
12253            "System", "Persistent", "Foreground",
12254            "Visible", "Perceptible",
12255            "Heavy Weight", "Backup",
12256            "A Services", "Home",
12257            "Previous", "B Services", "Cached"
12258    };
12259    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12260            "native",
12261            "sys", "pers", "fore",
12262            "vis", "percept",
12263            "heavy", "backup",
12264            "servicea", "home",
12265            "prev", "serviceb", "cached"
12266    };
12267
12268    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12269            long realtime, boolean isCheckinRequest, boolean isCompact) {
12270        if (isCheckinRequest || isCompact) {
12271            // short checkin version
12272            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12273        } else {
12274            pw.println("Applications Memory Usage (kB):");
12275            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12276        }
12277    }
12278
12279    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12280            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12281        boolean dumpDetails = false;
12282        boolean dumpFullDetails = false;
12283        boolean dumpDalvik = false;
12284        boolean oomOnly = false;
12285        boolean isCompact = false;
12286        boolean localOnly = false;
12287
12288        int opti = 0;
12289        while (opti < args.length) {
12290            String opt = args[opti];
12291            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12292                break;
12293            }
12294            opti++;
12295            if ("-a".equals(opt)) {
12296                dumpDetails = true;
12297                dumpFullDetails = true;
12298                dumpDalvik = true;
12299            } else if ("-d".equals(opt)) {
12300                dumpDalvik = true;
12301            } else if ("-c".equals(opt)) {
12302                isCompact = true;
12303            } else if ("--oom".equals(opt)) {
12304                oomOnly = true;
12305            } else if ("--local".equals(opt)) {
12306                localOnly = true;
12307            } else if ("-h".equals(opt)) {
12308                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12309                pw.println("  -a: include all available information for each process.");
12310                pw.println("  -d: include dalvik details when dumping process details.");
12311                pw.println("  -c: dump in a compact machine-parseable representation.");
12312                pw.println("  --oom: only show processes organized by oom adj.");
12313                pw.println("  --local: only collect details locally, don't call process.");
12314                pw.println("If [process] is specified it can be the name or ");
12315                pw.println("pid of a specific process to dump.");
12316                return;
12317            } else {
12318                pw.println("Unknown argument: " + opt + "; use -h for help");
12319            }
12320        }
12321
12322        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12323        long uptime = SystemClock.uptimeMillis();
12324        long realtime = SystemClock.elapsedRealtime();
12325        final long[] tmpLong = new long[1];
12326
12327        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12328        if (procs == null) {
12329            // No Java processes.  Maybe they want to print a native process.
12330            if (args != null && args.length > opti
12331                    && args[opti].charAt(0) != '-') {
12332                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12333                        = new ArrayList<ProcessCpuTracker.Stats>();
12334                updateCpuStatsNow();
12335                int findPid = -1;
12336                try {
12337                    findPid = Integer.parseInt(args[opti]);
12338                } catch (NumberFormatException e) {
12339                }
12340                synchronized (mProcessCpuThread) {
12341                    final int N = mProcessCpuTracker.countStats();
12342                    for (int i=0; i<N; i++) {
12343                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12344                        if (st.pid == findPid || (st.baseName != null
12345                                && st.baseName.equals(args[opti]))) {
12346                            nativeProcs.add(st);
12347                        }
12348                    }
12349                }
12350                if (nativeProcs.size() > 0) {
12351                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12352                            isCompact);
12353                    Debug.MemoryInfo mi = null;
12354                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12355                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12356                        final int pid = r.pid;
12357                        if (!isCheckinRequest && dumpDetails) {
12358                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12359                        }
12360                        if (mi == null) {
12361                            mi = new Debug.MemoryInfo();
12362                        }
12363                        if (dumpDetails || (!brief && !oomOnly)) {
12364                            Debug.getMemoryInfo(pid, mi);
12365                        } else {
12366                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12367                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12368                        }
12369                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12370                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12371                        if (isCheckinRequest) {
12372                            pw.println();
12373                        }
12374                    }
12375                    return;
12376                }
12377            }
12378            pw.println("No process found for: " + args[opti]);
12379            return;
12380        }
12381
12382        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12383            dumpDetails = true;
12384        }
12385
12386        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12387
12388        String[] innerArgs = new String[args.length-opti];
12389        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12390
12391        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12392        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12393        long nativePss=0, dalvikPss=0, otherPss=0;
12394        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12395
12396        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12397        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12398                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12399
12400        long totalPss = 0;
12401        long cachedPss = 0;
12402
12403        Debug.MemoryInfo mi = null;
12404        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12405            final ProcessRecord r = procs.get(i);
12406            final IApplicationThread thread;
12407            final int pid;
12408            final int oomAdj;
12409            final boolean hasActivities;
12410            synchronized (this) {
12411                thread = r.thread;
12412                pid = r.pid;
12413                oomAdj = r.getSetAdjWithServices();
12414                hasActivities = r.activities.size() > 0;
12415            }
12416            if (thread != null) {
12417                if (!isCheckinRequest && dumpDetails) {
12418                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12419                }
12420                if (mi == null) {
12421                    mi = new Debug.MemoryInfo();
12422                }
12423                if (dumpDetails || (!brief && !oomOnly)) {
12424                    Debug.getMemoryInfo(pid, mi);
12425                } else {
12426                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12427                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12428                }
12429                if (dumpDetails) {
12430                    if (localOnly) {
12431                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12432                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12433                        if (isCheckinRequest) {
12434                            pw.println();
12435                        }
12436                    } else {
12437                        try {
12438                            pw.flush();
12439                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12440                                    dumpDalvik, innerArgs);
12441                        } catch (RemoteException e) {
12442                            if (!isCheckinRequest) {
12443                                pw.println("Got RemoteException!");
12444                                pw.flush();
12445                            }
12446                        }
12447                    }
12448                }
12449
12450                final long myTotalPss = mi.getTotalPss();
12451                final long myTotalUss = mi.getTotalUss();
12452
12453                synchronized (this) {
12454                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12455                        // Record this for posterity if the process has been stable.
12456                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12457                    }
12458                }
12459
12460                if (!isCheckinRequest && mi != null) {
12461                    totalPss += myTotalPss;
12462                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12463                            (hasActivities ? " / activities)" : ")"),
12464                            r.processName, myTotalPss, pid, hasActivities);
12465                    procMems.add(pssItem);
12466                    procMemsMap.put(pid, pssItem);
12467
12468                    nativePss += mi.nativePss;
12469                    dalvikPss += mi.dalvikPss;
12470                    otherPss += mi.otherPss;
12471                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12472                        long mem = mi.getOtherPss(j);
12473                        miscPss[j] += mem;
12474                        otherPss -= mem;
12475                    }
12476
12477                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12478                        cachedPss += myTotalPss;
12479                    }
12480
12481                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12482                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12483                                || oomIndex == (oomPss.length-1)) {
12484                            oomPss[oomIndex] += myTotalPss;
12485                            if (oomProcs[oomIndex] == null) {
12486                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12487                            }
12488                            oomProcs[oomIndex].add(pssItem);
12489                            break;
12490                        }
12491                    }
12492                }
12493            }
12494        }
12495
12496        if (!isCheckinRequest && procs.size() > 1) {
12497            // If we are showing aggregations, also look for native processes to
12498            // include so that our aggregations are more accurate.
12499            updateCpuStatsNow();
12500            synchronized (mProcessCpuThread) {
12501                final int N = mProcessCpuTracker.countStats();
12502                for (int i=0; i<N; i++) {
12503                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12504                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12505                        if (mi == null) {
12506                            mi = new Debug.MemoryInfo();
12507                        }
12508                        if (!brief && !oomOnly) {
12509                            Debug.getMemoryInfo(st.pid, mi);
12510                        } else {
12511                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12512                            mi.nativePrivateDirty = (int)tmpLong[0];
12513                        }
12514
12515                        final long myTotalPss = mi.getTotalPss();
12516                        totalPss += myTotalPss;
12517
12518                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12519                                st.name, myTotalPss, st.pid, false);
12520                        procMems.add(pssItem);
12521
12522                        nativePss += mi.nativePss;
12523                        dalvikPss += mi.dalvikPss;
12524                        otherPss += mi.otherPss;
12525                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12526                            long mem = mi.getOtherPss(j);
12527                            miscPss[j] += mem;
12528                            otherPss -= mem;
12529                        }
12530                        oomPss[0] += myTotalPss;
12531                        if (oomProcs[0] == null) {
12532                            oomProcs[0] = new ArrayList<MemItem>();
12533                        }
12534                        oomProcs[0].add(pssItem);
12535                    }
12536                }
12537            }
12538
12539            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12540
12541            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12542            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12543            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12544            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12545                String label = Debug.MemoryInfo.getOtherLabel(j);
12546                catMems.add(new MemItem(label, label, miscPss[j], j));
12547            }
12548
12549            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12550            for (int j=0; j<oomPss.length; j++) {
12551                if (oomPss[j] != 0) {
12552                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12553                            : DUMP_MEM_OOM_LABEL[j];
12554                    MemItem item = new MemItem(label, label, oomPss[j],
12555                            DUMP_MEM_OOM_ADJ[j]);
12556                    item.subitems = oomProcs[j];
12557                    oomMems.add(item);
12558                }
12559            }
12560
12561            if (!brief && !oomOnly && !isCompact) {
12562                pw.println();
12563                pw.println("Total PSS by process:");
12564                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12565                pw.println();
12566            }
12567            if (!isCompact) {
12568                pw.println("Total PSS by OOM adjustment:");
12569            }
12570            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12571            if (!brief && !oomOnly) {
12572                PrintWriter out = categoryPw != null ? categoryPw : pw;
12573                if (!isCompact) {
12574                    out.println();
12575                    out.println("Total PSS by category:");
12576                }
12577                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12578            }
12579            if (!isCompact) {
12580                pw.println();
12581            }
12582            MemInfoReader memInfo = new MemInfoReader();
12583            memInfo.readMemInfo();
12584            if (!brief) {
12585                if (!isCompact) {
12586                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12587                    pw.print(" kB (status ");
12588                    switch (mLastMemoryLevel) {
12589                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12590                            pw.println("normal)");
12591                            break;
12592                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12593                            pw.println("moderate)");
12594                            break;
12595                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12596                            pw.println("low)");
12597                            break;
12598                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12599                            pw.println("critical)");
12600                            break;
12601                        default:
12602                            pw.print(mLastMemoryLevel);
12603                            pw.println(")");
12604                            break;
12605                    }
12606                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12607                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12608                            pw.print(cachedPss); pw.print(" cached pss + ");
12609                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12610                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12611                } else {
12612                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12613                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12614                            + memInfo.getFreeSizeKb()); pw.print(",");
12615                    pw.println(totalPss - cachedPss);
12616                }
12617            }
12618            if (!isCompact) {
12619                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12620                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12621                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12622                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12623                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12624                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12625                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12626                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12627                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12628                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12629                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12630            }
12631            if (!brief) {
12632                if (memInfo.getZramTotalSizeKb() != 0) {
12633                    if (!isCompact) {
12634                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12635                                pw.print(" kB physical used for ");
12636                                pw.print(memInfo.getSwapTotalSizeKb()
12637                                        - memInfo.getSwapFreeSizeKb());
12638                                pw.print(" kB in swap (");
12639                                pw.print(memInfo.getSwapTotalSizeKb());
12640                                pw.println(" kB total swap)");
12641                    } else {
12642                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12643                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12644                                pw.println(memInfo.getSwapFreeSizeKb());
12645                    }
12646                }
12647                final int[] SINGLE_LONG_FORMAT = new int[] {
12648                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12649                };
12650                long[] longOut = new long[1];
12651                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12652                        SINGLE_LONG_FORMAT, null, longOut, null);
12653                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12654                longOut[0] = 0;
12655                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12656                        SINGLE_LONG_FORMAT, null, longOut, null);
12657                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12658                longOut[0] = 0;
12659                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12660                        SINGLE_LONG_FORMAT, null, longOut, null);
12661                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12662                longOut[0] = 0;
12663                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12664                        SINGLE_LONG_FORMAT, null, longOut, null);
12665                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12666                if (!isCompact) {
12667                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12668                        pw.print("      KSM: "); pw.print(sharing);
12669                                pw.print(" kB saved from shared ");
12670                                pw.print(shared); pw.println(" kB");
12671                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12672                                pw.print(voltile); pw.println(" kB volatile");
12673                    }
12674                    pw.print("   Tuning: ");
12675                    pw.print(ActivityManager.staticGetMemoryClass());
12676                    pw.print(" (large ");
12677                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12678                    pw.print("), oom ");
12679                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12680                    pw.print(" kB");
12681                    pw.print(", restore limit ");
12682                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12683                    pw.print(" kB");
12684                    if (ActivityManager.isLowRamDeviceStatic()) {
12685                        pw.print(" (low-ram)");
12686                    }
12687                    if (ActivityManager.isHighEndGfx()) {
12688                        pw.print(" (high-end-gfx)");
12689                    }
12690                    pw.println();
12691                } else {
12692                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12693                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12694                    pw.println(voltile);
12695                    pw.print("tuning,");
12696                    pw.print(ActivityManager.staticGetMemoryClass());
12697                    pw.print(',');
12698                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12699                    pw.print(',');
12700                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12701                    if (ActivityManager.isLowRamDeviceStatic()) {
12702                        pw.print(",low-ram");
12703                    }
12704                    if (ActivityManager.isHighEndGfx()) {
12705                        pw.print(",high-end-gfx");
12706                    }
12707                    pw.println();
12708                }
12709            }
12710        }
12711    }
12712
12713    /**
12714     * Searches array of arguments for the specified string
12715     * @param args array of argument strings
12716     * @param value value to search for
12717     * @return true if the value is contained in the array
12718     */
12719    private static boolean scanArgs(String[] args, String value) {
12720        if (args != null) {
12721            for (String arg : args) {
12722                if (value.equals(arg)) {
12723                    return true;
12724                }
12725            }
12726        }
12727        return false;
12728    }
12729
12730    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12731            ContentProviderRecord cpr, boolean always) {
12732        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12733
12734        if (!inLaunching || always) {
12735            synchronized (cpr) {
12736                cpr.launchingApp = null;
12737                cpr.notifyAll();
12738            }
12739            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12740            String names[] = cpr.info.authority.split(";");
12741            for (int j = 0; j < names.length; j++) {
12742                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12743            }
12744        }
12745
12746        for (int i=0; i<cpr.connections.size(); i++) {
12747            ContentProviderConnection conn = cpr.connections.get(i);
12748            if (conn.waiting) {
12749                // If this connection is waiting for the provider, then we don't
12750                // need to mess with its process unless we are always removing
12751                // or for some reason the provider is not currently launching.
12752                if (inLaunching && !always) {
12753                    continue;
12754                }
12755            }
12756            ProcessRecord capp = conn.client;
12757            conn.dead = true;
12758            if (conn.stableCount > 0) {
12759                if (!capp.persistent && capp.thread != null
12760                        && capp.pid != 0
12761                        && capp.pid != MY_PID) {
12762                    killUnneededProcessLocked(capp, "depends on provider "
12763                            + cpr.name.flattenToShortString()
12764                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12765                }
12766            } else if (capp.thread != null && conn.provider.provider != null) {
12767                try {
12768                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12769                } catch (RemoteException e) {
12770                }
12771                // In the protocol here, we don't expect the client to correctly
12772                // clean up this connection, we'll just remove it.
12773                cpr.connections.remove(i);
12774                conn.client.conProviders.remove(conn);
12775            }
12776        }
12777
12778        if (inLaunching && always) {
12779            mLaunchingProviders.remove(cpr);
12780        }
12781        return inLaunching;
12782    }
12783
12784    /**
12785     * Main code for cleaning up a process when it has gone away.  This is
12786     * called both as a result of the process dying, or directly when stopping
12787     * a process when running in single process mode.
12788     */
12789    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12790            boolean restarting, boolean allowRestart, int index) {
12791        if (index >= 0) {
12792            removeLruProcessLocked(app);
12793            ProcessList.remove(app.pid);
12794        }
12795
12796        mProcessesToGc.remove(app);
12797        mPendingPssProcesses.remove(app);
12798
12799        // Dismiss any open dialogs.
12800        if (app.crashDialog != null && !app.forceCrashReport) {
12801            app.crashDialog.dismiss();
12802            app.crashDialog = null;
12803        }
12804        if (app.anrDialog != null) {
12805            app.anrDialog.dismiss();
12806            app.anrDialog = null;
12807        }
12808        if (app.waitDialog != null) {
12809            app.waitDialog.dismiss();
12810            app.waitDialog = null;
12811        }
12812
12813        app.crashing = false;
12814        app.notResponding = false;
12815
12816        app.resetPackageList(mProcessStats);
12817        app.unlinkDeathRecipient();
12818        app.makeInactive(mProcessStats);
12819        app.forcingToForeground = null;
12820        updateProcessForegroundLocked(app, false, false);
12821        app.foregroundActivities = false;
12822        app.hasShownUi = false;
12823        app.treatLikeActivity = false;
12824        app.hasAboveClient = false;
12825        app.hasClientActivities = false;
12826
12827        mServices.killServicesLocked(app, allowRestart);
12828
12829        boolean restart = false;
12830
12831        // Remove published content providers.
12832        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12833            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12834            final boolean always = app.bad || !allowRestart;
12835            if (removeDyingProviderLocked(app, cpr, always) || always) {
12836                // We left the provider in the launching list, need to
12837                // restart it.
12838                restart = true;
12839            }
12840
12841            cpr.provider = null;
12842            cpr.proc = null;
12843        }
12844        app.pubProviders.clear();
12845
12846        // Take care of any launching providers waiting for this process.
12847        if (checkAppInLaunchingProvidersLocked(app, false)) {
12848            restart = true;
12849        }
12850
12851        // Unregister from connected content providers.
12852        if (!app.conProviders.isEmpty()) {
12853            for (int i=0; i<app.conProviders.size(); i++) {
12854                ContentProviderConnection conn = app.conProviders.get(i);
12855                conn.provider.connections.remove(conn);
12856            }
12857            app.conProviders.clear();
12858        }
12859
12860        // At this point there may be remaining entries in mLaunchingProviders
12861        // where we were the only one waiting, so they are no longer of use.
12862        // Look for these and clean up if found.
12863        // XXX Commented out for now.  Trying to figure out a way to reproduce
12864        // the actual situation to identify what is actually going on.
12865        if (false) {
12866            for (int i=0; i<mLaunchingProviders.size(); i++) {
12867                ContentProviderRecord cpr = (ContentProviderRecord)
12868                        mLaunchingProviders.get(i);
12869                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12870                    synchronized (cpr) {
12871                        cpr.launchingApp = null;
12872                        cpr.notifyAll();
12873                    }
12874                }
12875            }
12876        }
12877
12878        skipCurrentReceiverLocked(app);
12879
12880        // Unregister any receivers.
12881        for (int i=app.receivers.size()-1; i>=0; i--) {
12882            removeReceiverLocked(app.receivers.valueAt(i));
12883        }
12884        app.receivers.clear();
12885
12886        // If the app is undergoing backup, tell the backup manager about it
12887        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12888            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12889                    + mBackupTarget.appInfo + " died during backup");
12890            try {
12891                IBackupManager bm = IBackupManager.Stub.asInterface(
12892                        ServiceManager.getService(Context.BACKUP_SERVICE));
12893                bm.agentDisconnected(app.info.packageName);
12894            } catch (RemoteException e) {
12895                // can't happen; backup manager is local
12896            }
12897        }
12898
12899        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12900            ProcessChangeItem item = mPendingProcessChanges.get(i);
12901            if (item.pid == app.pid) {
12902                mPendingProcessChanges.remove(i);
12903                mAvailProcessChanges.add(item);
12904            }
12905        }
12906        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12907
12908        // If the caller is restarting this app, then leave it in its
12909        // current lists and let the caller take care of it.
12910        if (restarting) {
12911            return;
12912        }
12913
12914        if (!app.persistent || app.isolated) {
12915            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12916                    "Removing non-persistent process during cleanup: " + app);
12917            mProcessNames.remove(app.processName, app.uid);
12918            mIsolatedProcesses.remove(app.uid);
12919            if (mHeavyWeightProcess == app) {
12920                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12921                        mHeavyWeightProcess.userId, 0));
12922                mHeavyWeightProcess = null;
12923            }
12924        } else if (!app.removed) {
12925            // This app is persistent, so we need to keep its record around.
12926            // If it is not already on the pending app list, add it there
12927            // and start a new process for it.
12928            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12929                mPersistentStartingProcesses.add(app);
12930                restart = true;
12931            }
12932        }
12933        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12934                "Clean-up removing on hold: " + app);
12935        mProcessesOnHold.remove(app);
12936
12937        if (app == mHomeProcess) {
12938            mHomeProcess = null;
12939        }
12940        if (app == mPreviousProcess) {
12941            mPreviousProcess = null;
12942        }
12943
12944        if (restart && !app.isolated) {
12945            // We have components that still need to be running in the
12946            // process, so re-launch it.
12947            mProcessNames.put(app.processName, app.uid, app);
12948            startProcessLocked(app, "restart", app.processName);
12949        } else if (app.pid > 0 && app.pid != MY_PID) {
12950            // Goodbye!
12951            boolean removed;
12952            synchronized (mPidsSelfLocked) {
12953                mPidsSelfLocked.remove(app.pid);
12954                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12955            }
12956            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12957                    app.processName, app.info.uid);
12958            if (app.isolated) {
12959                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12960            }
12961            app.setPid(0);
12962        }
12963    }
12964
12965    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12966        // Look through the content providers we are waiting to have launched,
12967        // and if any run in this process then either schedule a restart of
12968        // the process or kill the client waiting for it if this process has
12969        // gone bad.
12970        int NL = mLaunchingProviders.size();
12971        boolean restart = false;
12972        for (int i=0; i<NL; i++) {
12973            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12974            if (cpr.launchingApp == app) {
12975                if (!alwaysBad && !app.bad) {
12976                    restart = true;
12977                } else {
12978                    removeDyingProviderLocked(app, cpr, true);
12979                    // cpr should have been removed from mLaunchingProviders
12980                    NL = mLaunchingProviders.size();
12981                    i--;
12982                }
12983            }
12984        }
12985        return restart;
12986    }
12987
12988    // =========================================================
12989    // SERVICES
12990    // =========================================================
12991
12992    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12993            int flags) {
12994        enforceNotIsolatedCaller("getServices");
12995        synchronized (this) {
12996            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12997        }
12998    }
12999
13000    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13001        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13002        synchronized (this) {
13003            return mServices.getRunningServiceControlPanelLocked(name);
13004        }
13005    }
13006
13007    public ComponentName startService(IApplicationThread caller, Intent service,
13008            String resolvedType, int userId) {
13009        enforceNotIsolatedCaller("startService");
13010        // Refuse possible leaked file descriptors
13011        if (service != null && service.hasFileDescriptors() == true) {
13012            throw new IllegalArgumentException("File descriptors passed in Intent");
13013        }
13014
13015        if (DEBUG_SERVICE)
13016            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13017        synchronized(this) {
13018            final int callingPid = Binder.getCallingPid();
13019            final int callingUid = Binder.getCallingUid();
13020            final long origId = Binder.clearCallingIdentity();
13021            ComponentName res = mServices.startServiceLocked(caller, service,
13022                    resolvedType, callingPid, callingUid, userId);
13023            Binder.restoreCallingIdentity(origId);
13024            return res;
13025        }
13026    }
13027
13028    ComponentName startServiceInPackage(int uid,
13029            Intent service, String resolvedType, int userId) {
13030        synchronized(this) {
13031            if (DEBUG_SERVICE)
13032                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13033            final long origId = Binder.clearCallingIdentity();
13034            ComponentName res = mServices.startServiceLocked(null, service,
13035                    resolvedType, -1, uid, userId);
13036            Binder.restoreCallingIdentity(origId);
13037            return res;
13038        }
13039    }
13040
13041    public int stopService(IApplicationThread caller, Intent service,
13042            String resolvedType, int userId) {
13043        enforceNotIsolatedCaller("stopService");
13044        // Refuse possible leaked file descriptors
13045        if (service != null && service.hasFileDescriptors() == true) {
13046            throw new IllegalArgumentException("File descriptors passed in Intent");
13047        }
13048
13049        synchronized(this) {
13050            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13051        }
13052    }
13053
13054    public IBinder peekService(Intent service, String resolvedType) {
13055        enforceNotIsolatedCaller("peekService");
13056        // Refuse possible leaked file descriptors
13057        if (service != null && service.hasFileDescriptors() == true) {
13058            throw new IllegalArgumentException("File descriptors passed in Intent");
13059        }
13060        synchronized(this) {
13061            return mServices.peekServiceLocked(service, resolvedType);
13062        }
13063    }
13064
13065    public boolean stopServiceToken(ComponentName className, IBinder token,
13066            int startId) {
13067        synchronized(this) {
13068            return mServices.stopServiceTokenLocked(className, token, startId);
13069        }
13070    }
13071
13072    public void setServiceForeground(ComponentName className, IBinder token,
13073            int id, Notification notification, boolean removeNotification) {
13074        synchronized(this) {
13075            mServices.setServiceForegroundLocked(className, token, id, notification,
13076                    removeNotification);
13077        }
13078    }
13079
13080    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13081            boolean requireFull, String name, String callerPackage) {
13082        final int callingUserId = UserHandle.getUserId(callingUid);
13083        if (callingUserId != userId) {
13084            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13085                if ((requireFull || checkComponentPermission(
13086                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13087                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13088                        && checkComponentPermission(
13089                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13090                                callingPid, callingUid, -1, true)
13091                                != PackageManager.PERMISSION_GRANTED) {
13092                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13093                        // In this case, they would like to just execute as their
13094                        // owner user instead of failing.
13095                        userId = callingUserId;
13096                    } else {
13097                        StringBuilder builder = new StringBuilder(128);
13098                        builder.append("Permission Denial: ");
13099                        builder.append(name);
13100                        if (callerPackage != null) {
13101                            builder.append(" from ");
13102                            builder.append(callerPackage);
13103                        }
13104                        builder.append(" asks to run as user ");
13105                        builder.append(userId);
13106                        builder.append(" but is calling from user ");
13107                        builder.append(UserHandle.getUserId(callingUid));
13108                        builder.append("; this requires ");
13109                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13110                        if (!requireFull) {
13111                            builder.append(" or ");
13112                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13113                        }
13114                        String msg = builder.toString();
13115                        Slog.w(TAG, msg);
13116                        throw new SecurityException(msg);
13117                    }
13118                }
13119            }
13120            if (userId == UserHandle.USER_CURRENT
13121                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13122                // Note that we may be accessing this outside of a lock...
13123                // shouldn't be a big deal, if this is being called outside
13124                // of a locked context there is intrinsically a race with
13125                // the value the caller will receive and someone else changing it.
13126                userId = mCurrentUserId;
13127            }
13128            if (!allowAll && userId < 0) {
13129                throw new IllegalArgumentException(
13130                        "Call does not support special user #" + userId);
13131            }
13132        }
13133        return userId;
13134    }
13135
13136    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13137            String className, int flags) {
13138        boolean result = false;
13139        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13140            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13141                if (ActivityManager.checkUidPermission(
13142                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13143                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13144                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13145                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13146                            + " requests FLAG_SINGLE_USER, but app does not hold "
13147                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13148                    Slog.w(TAG, msg);
13149                    throw new SecurityException(msg);
13150                }
13151                result = true;
13152            }
13153        } else if (componentProcessName == aInfo.packageName) {
13154            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13155        } else if ("system".equals(componentProcessName)) {
13156            result = true;
13157        }
13158        if (DEBUG_MU) {
13159            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13160                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13161        }
13162        return result;
13163    }
13164
13165    public int bindService(IApplicationThread caller, IBinder token,
13166            Intent service, String resolvedType,
13167            IServiceConnection connection, int flags, int userId) {
13168        enforceNotIsolatedCaller("bindService");
13169        // Refuse possible leaked file descriptors
13170        if (service != null && service.hasFileDescriptors() == true) {
13171            throw new IllegalArgumentException("File descriptors passed in Intent");
13172        }
13173
13174        synchronized(this) {
13175            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13176                    connection, flags, userId);
13177        }
13178    }
13179
13180    public boolean unbindService(IServiceConnection connection) {
13181        synchronized (this) {
13182            return mServices.unbindServiceLocked(connection);
13183        }
13184    }
13185
13186    public void publishService(IBinder token, Intent intent, IBinder service) {
13187        // Refuse possible leaked file descriptors
13188        if (intent != null && intent.hasFileDescriptors() == true) {
13189            throw new IllegalArgumentException("File descriptors passed in Intent");
13190        }
13191
13192        synchronized(this) {
13193            if (!(token instanceof ServiceRecord)) {
13194                throw new IllegalArgumentException("Invalid service token");
13195            }
13196            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13197        }
13198    }
13199
13200    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13201        // Refuse possible leaked file descriptors
13202        if (intent != null && intent.hasFileDescriptors() == true) {
13203            throw new IllegalArgumentException("File descriptors passed in Intent");
13204        }
13205
13206        synchronized(this) {
13207            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13208        }
13209    }
13210
13211    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13212        synchronized(this) {
13213            if (!(token instanceof ServiceRecord)) {
13214                throw new IllegalArgumentException("Invalid service token");
13215            }
13216            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13217        }
13218    }
13219
13220    // =========================================================
13221    // BACKUP AND RESTORE
13222    // =========================================================
13223
13224    // Cause the target app to be launched if necessary and its backup agent
13225    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13226    // activity manager to announce its creation.
13227    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13228        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13229        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13230
13231        synchronized(this) {
13232            // !!! TODO: currently no check here that we're already bound
13233            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13234            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13235            synchronized (stats) {
13236                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13237            }
13238
13239            // Backup agent is now in use, its package can't be stopped.
13240            try {
13241                AppGlobals.getPackageManager().setPackageStoppedState(
13242                        app.packageName, false, UserHandle.getUserId(app.uid));
13243            } catch (RemoteException e) {
13244            } catch (IllegalArgumentException e) {
13245                Slog.w(TAG, "Failed trying to unstop package "
13246                        + app.packageName + ": " + e);
13247            }
13248
13249            BackupRecord r = new BackupRecord(ss, app, backupMode);
13250            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13251                    ? new ComponentName(app.packageName, app.backupAgentName)
13252                    : new ComponentName("android", "FullBackupAgent");
13253            // startProcessLocked() returns existing proc's record if it's already running
13254            ProcessRecord proc = startProcessLocked(app.processName, app,
13255                    false, 0, "backup", hostingName, false, false, false);
13256            if (proc == null) {
13257                Slog.e(TAG, "Unable to start backup agent process " + r);
13258                return false;
13259            }
13260
13261            r.app = proc;
13262            mBackupTarget = r;
13263            mBackupAppName = app.packageName;
13264
13265            // Try not to kill the process during backup
13266            updateOomAdjLocked(proc);
13267
13268            // If the process is already attached, schedule the creation of the backup agent now.
13269            // If it is not yet live, this will be done when it attaches to the framework.
13270            if (proc.thread != null) {
13271                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13272                try {
13273                    proc.thread.scheduleCreateBackupAgent(app,
13274                            compatibilityInfoForPackageLocked(app), backupMode);
13275                } catch (RemoteException e) {
13276                    // Will time out on the backup manager side
13277                }
13278            } else {
13279                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13280            }
13281            // Invariants: at this point, the target app process exists and the application
13282            // is either already running or in the process of coming up.  mBackupTarget and
13283            // mBackupAppName describe the app, so that when it binds back to the AM we
13284            // know that it's scheduled for a backup-agent operation.
13285        }
13286
13287        return true;
13288    }
13289
13290    @Override
13291    public void clearPendingBackup() {
13292        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13293        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13294
13295        synchronized (this) {
13296            mBackupTarget = null;
13297            mBackupAppName = null;
13298        }
13299    }
13300
13301    // A backup agent has just come up
13302    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13303        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13304                + " = " + agent);
13305
13306        synchronized(this) {
13307            if (!agentPackageName.equals(mBackupAppName)) {
13308                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13309                return;
13310            }
13311        }
13312
13313        long oldIdent = Binder.clearCallingIdentity();
13314        try {
13315            IBackupManager bm = IBackupManager.Stub.asInterface(
13316                    ServiceManager.getService(Context.BACKUP_SERVICE));
13317            bm.agentConnected(agentPackageName, agent);
13318        } catch (RemoteException e) {
13319            // can't happen; the backup manager service is local
13320        } catch (Exception e) {
13321            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13322            e.printStackTrace();
13323        } finally {
13324            Binder.restoreCallingIdentity(oldIdent);
13325        }
13326    }
13327
13328    // done with this agent
13329    public void unbindBackupAgent(ApplicationInfo appInfo) {
13330        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13331        if (appInfo == null) {
13332            Slog.w(TAG, "unbind backup agent for null app");
13333            return;
13334        }
13335
13336        synchronized(this) {
13337            try {
13338                if (mBackupAppName == null) {
13339                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13340                    return;
13341                }
13342
13343                if (!mBackupAppName.equals(appInfo.packageName)) {
13344                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13345                    return;
13346                }
13347
13348                // Not backing this app up any more; reset its OOM adjustment
13349                final ProcessRecord proc = mBackupTarget.app;
13350                updateOomAdjLocked(proc);
13351
13352                // If the app crashed during backup, 'thread' will be null here
13353                if (proc.thread != null) {
13354                    try {
13355                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13356                                compatibilityInfoForPackageLocked(appInfo));
13357                    } catch (Exception e) {
13358                        Slog.e(TAG, "Exception when unbinding backup agent:");
13359                        e.printStackTrace();
13360                    }
13361                }
13362            } finally {
13363                mBackupTarget = null;
13364                mBackupAppName = null;
13365            }
13366        }
13367    }
13368    // =========================================================
13369    // BROADCASTS
13370    // =========================================================
13371
13372    private final List getStickiesLocked(String action, IntentFilter filter,
13373            List cur, int userId) {
13374        final ContentResolver resolver = mContext.getContentResolver();
13375        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13376        if (stickies == null) {
13377            return cur;
13378        }
13379        final ArrayList<Intent> list = stickies.get(action);
13380        if (list == null) {
13381            return cur;
13382        }
13383        int N = list.size();
13384        for (int i=0; i<N; i++) {
13385            Intent intent = list.get(i);
13386            if (filter.match(resolver, intent, true, TAG) >= 0) {
13387                if (cur == null) {
13388                    cur = new ArrayList<Intent>();
13389                }
13390                cur.add(intent);
13391            }
13392        }
13393        return cur;
13394    }
13395
13396    boolean isPendingBroadcastProcessLocked(int pid) {
13397        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13398                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13399    }
13400
13401    void skipPendingBroadcastLocked(int pid) {
13402            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13403            for (BroadcastQueue queue : mBroadcastQueues) {
13404                queue.skipPendingBroadcastLocked(pid);
13405            }
13406    }
13407
13408    // The app just attached; send any pending broadcasts that it should receive
13409    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13410        boolean didSomething = false;
13411        for (BroadcastQueue queue : mBroadcastQueues) {
13412            didSomething |= queue.sendPendingBroadcastsLocked(app);
13413        }
13414        return didSomething;
13415    }
13416
13417    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13418            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13419        enforceNotIsolatedCaller("registerReceiver");
13420        int callingUid;
13421        int callingPid;
13422        synchronized(this) {
13423            ProcessRecord callerApp = null;
13424            if (caller != null) {
13425                callerApp = getRecordForAppLocked(caller);
13426                if (callerApp == null) {
13427                    throw new SecurityException(
13428                            "Unable to find app for caller " + caller
13429                            + " (pid=" + Binder.getCallingPid()
13430                            + ") when registering receiver " + receiver);
13431                }
13432                if (callerApp.info.uid != Process.SYSTEM_UID &&
13433                        !callerApp.pkgList.containsKey(callerPackage) &&
13434                        !"android".equals(callerPackage)) {
13435                    throw new SecurityException("Given caller package " + callerPackage
13436                            + " is not running in process " + callerApp);
13437                }
13438                callingUid = callerApp.info.uid;
13439                callingPid = callerApp.pid;
13440            } else {
13441                callerPackage = null;
13442                callingUid = Binder.getCallingUid();
13443                callingPid = Binder.getCallingPid();
13444            }
13445
13446            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13447                    true, true, "registerReceiver", callerPackage);
13448
13449            List allSticky = null;
13450
13451            // Look for any matching sticky broadcasts...
13452            Iterator actions = filter.actionsIterator();
13453            if (actions != null) {
13454                while (actions.hasNext()) {
13455                    String action = (String)actions.next();
13456                    allSticky = getStickiesLocked(action, filter, allSticky,
13457                            UserHandle.USER_ALL);
13458                    allSticky = getStickiesLocked(action, filter, allSticky,
13459                            UserHandle.getUserId(callingUid));
13460                }
13461            } else {
13462                allSticky = getStickiesLocked(null, filter, allSticky,
13463                        UserHandle.USER_ALL);
13464                allSticky = getStickiesLocked(null, filter, allSticky,
13465                        UserHandle.getUserId(callingUid));
13466            }
13467
13468            // The first sticky in the list is returned directly back to
13469            // the client.
13470            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13471
13472            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13473                    + ": " + sticky);
13474
13475            if (receiver == null) {
13476                return sticky;
13477            }
13478
13479            ReceiverList rl
13480                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13481            if (rl == null) {
13482                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13483                        userId, receiver);
13484                if (rl.app != null) {
13485                    rl.app.receivers.add(rl);
13486                } else {
13487                    try {
13488                        receiver.asBinder().linkToDeath(rl, 0);
13489                    } catch (RemoteException e) {
13490                        return sticky;
13491                    }
13492                    rl.linkedToDeath = true;
13493                }
13494                mRegisteredReceivers.put(receiver.asBinder(), rl);
13495            } else if (rl.uid != callingUid) {
13496                throw new IllegalArgumentException(
13497                        "Receiver requested to register for uid " + callingUid
13498                        + " was previously registered for uid " + rl.uid);
13499            } else if (rl.pid != callingPid) {
13500                throw new IllegalArgumentException(
13501                        "Receiver requested to register for pid " + callingPid
13502                        + " was previously registered for pid " + rl.pid);
13503            } else if (rl.userId != userId) {
13504                throw new IllegalArgumentException(
13505                        "Receiver requested to register for user " + userId
13506                        + " was previously registered for user " + rl.userId);
13507            }
13508            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13509                    permission, callingUid, userId);
13510            rl.add(bf);
13511            if (!bf.debugCheck()) {
13512                Slog.w(TAG, "==> For Dynamic broadast");
13513            }
13514            mReceiverResolver.addFilter(bf);
13515
13516            // Enqueue broadcasts for all existing stickies that match
13517            // this filter.
13518            if (allSticky != null) {
13519                ArrayList receivers = new ArrayList();
13520                receivers.add(bf);
13521
13522                int N = allSticky.size();
13523                for (int i=0; i<N; i++) {
13524                    Intent intent = (Intent)allSticky.get(i);
13525                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13526                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13527                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13528                            null, null, false, true, true, -1);
13529                    queue.enqueueParallelBroadcastLocked(r);
13530                    queue.scheduleBroadcastsLocked();
13531                }
13532            }
13533
13534            return sticky;
13535        }
13536    }
13537
13538    public void unregisterReceiver(IIntentReceiver receiver) {
13539        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13540
13541        final long origId = Binder.clearCallingIdentity();
13542        try {
13543            boolean doTrim = false;
13544
13545            synchronized(this) {
13546                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13547                if (rl != null) {
13548                    if (rl.curBroadcast != null) {
13549                        BroadcastRecord r = rl.curBroadcast;
13550                        final boolean doNext = finishReceiverLocked(
13551                                receiver.asBinder(), r.resultCode, r.resultData,
13552                                r.resultExtras, r.resultAbort);
13553                        if (doNext) {
13554                            doTrim = true;
13555                            r.queue.processNextBroadcast(false);
13556                        }
13557                    }
13558
13559                    if (rl.app != null) {
13560                        rl.app.receivers.remove(rl);
13561                    }
13562                    removeReceiverLocked(rl);
13563                    if (rl.linkedToDeath) {
13564                        rl.linkedToDeath = false;
13565                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13566                    }
13567                }
13568            }
13569
13570            // If we actually concluded any broadcasts, we might now be able
13571            // to trim the recipients' apps from our working set
13572            if (doTrim) {
13573                trimApplications();
13574                return;
13575            }
13576
13577        } finally {
13578            Binder.restoreCallingIdentity(origId);
13579        }
13580    }
13581
13582    void removeReceiverLocked(ReceiverList rl) {
13583        mRegisteredReceivers.remove(rl.receiver.asBinder());
13584        int N = rl.size();
13585        for (int i=0; i<N; i++) {
13586            mReceiverResolver.removeFilter(rl.get(i));
13587        }
13588    }
13589
13590    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13591        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13592            ProcessRecord r = mLruProcesses.get(i);
13593            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13594                try {
13595                    r.thread.dispatchPackageBroadcast(cmd, packages);
13596                } catch (RemoteException ex) {
13597                }
13598            }
13599        }
13600    }
13601
13602    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13603            int[] users) {
13604        List<ResolveInfo> receivers = null;
13605        try {
13606            HashSet<ComponentName> singleUserReceivers = null;
13607            boolean scannedFirstReceivers = false;
13608            for (int user : users) {
13609                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13610                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13611                if (user != 0 && newReceivers != null) {
13612                    // If this is not the primary user, we need to check for
13613                    // any receivers that should be filtered out.
13614                    for (int i=0; i<newReceivers.size(); i++) {
13615                        ResolveInfo ri = newReceivers.get(i);
13616                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13617                            newReceivers.remove(i);
13618                            i--;
13619                        }
13620                    }
13621                }
13622                if (newReceivers != null && newReceivers.size() == 0) {
13623                    newReceivers = null;
13624                }
13625                if (receivers == null) {
13626                    receivers = newReceivers;
13627                } else if (newReceivers != null) {
13628                    // We need to concatenate the additional receivers
13629                    // found with what we have do far.  This would be easy,
13630                    // but we also need to de-dup any receivers that are
13631                    // singleUser.
13632                    if (!scannedFirstReceivers) {
13633                        // Collect any single user receivers we had already retrieved.
13634                        scannedFirstReceivers = true;
13635                        for (int i=0; i<receivers.size(); i++) {
13636                            ResolveInfo ri = receivers.get(i);
13637                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13638                                ComponentName cn = new ComponentName(
13639                                        ri.activityInfo.packageName, ri.activityInfo.name);
13640                                if (singleUserReceivers == null) {
13641                                    singleUserReceivers = new HashSet<ComponentName>();
13642                                }
13643                                singleUserReceivers.add(cn);
13644                            }
13645                        }
13646                    }
13647                    // Add the new results to the existing results, tracking
13648                    // and de-dupping single user receivers.
13649                    for (int i=0; i<newReceivers.size(); i++) {
13650                        ResolveInfo ri = newReceivers.get(i);
13651                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13652                            ComponentName cn = new ComponentName(
13653                                    ri.activityInfo.packageName, ri.activityInfo.name);
13654                            if (singleUserReceivers == null) {
13655                                singleUserReceivers = new HashSet<ComponentName>();
13656                            }
13657                            if (!singleUserReceivers.contains(cn)) {
13658                                singleUserReceivers.add(cn);
13659                                receivers.add(ri);
13660                            }
13661                        } else {
13662                            receivers.add(ri);
13663                        }
13664                    }
13665                }
13666            }
13667        } catch (RemoteException ex) {
13668            // pm is in same process, this will never happen.
13669        }
13670        return receivers;
13671    }
13672
13673    private final int broadcastIntentLocked(ProcessRecord callerApp,
13674            String callerPackage, Intent intent, String resolvedType,
13675            IIntentReceiver resultTo, int resultCode, String resultData,
13676            Bundle map, String requiredPermission, int appOp,
13677            boolean ordered, boolean sticky, int callingPid, int callingUid,
13678            int userId) {
13679        intent = new Intent(intent);
13680
13681        // By default broadcasts do not go to stopped apps.
13682        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13683
13684        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13685            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13686            + " ordered=" + ordered + " userid=" + userId);
13687        if ((resultTo != null) && !ordered) {
13688            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13689        }
13690
13691        userId = handleIncomingUser(callingPid, callingUid, userId,
13692                true, false, "broadcast", callerPackage);
13693
13694        // Make sure that the user who is receiving this broadcast is started.
13695        // If not, we will just skip it.
13696        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13697            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13698                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13699                Slog.w(TAG, "Skipping broadcast of " + intent
13700                        + ": user " + userId + " is stopped");
13701                return ActivityManager.BROADCAST_SUCCESS;
13702            }
13703        }
13704
13705        /*
13706         * Prevent non-system code (defined here to be non-persistent
13707         * processes) from sending protected broadcasts.
13708         */
13709        int callingAppId = UserHandle.getAppId(callingUid);
13710        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13711            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13712            callingUid == 0) {
13713            // Always okay.
13714        } else if (callerApp == null || !callerApp.persistent) {
13715            try {
13716                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13717                        intent.getAction())) {
13718                    String msg = "Permission Denial: not allowed to send broadcast "
13719                            + intent.getAction() + " from pid="
13720                            + callingPid + ", uid=" + callingUid;
13721                    Slog.w(TAG, msg);
13722                    throw new SecurityException(msg);
13723                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13724                    // Special case for compatibility: we don't want apps to send this,
13725                    // but historically it has not been protected and apps may be using it
13726                    // to poke their own app widget.  So, instead of making it protected,
13727                    // just limit it to the caller.
13728                    if (callerApp == null) {
13729                        String msg = "Permission Denial: not allowed to send broadcast "
13730                                + intent.getAction() + " from unknown caller.";
13731                        Slog.w(TAG, msg);
13732                        throw new SecurityException(msg);
13733                    } else if (intent.getComponent() != null) {
13734                        // They are good enough to send to an explicit component...  verify
13735                        // it is being sent to the calling app.
13736                        if (!intent.getComponent().getPackageName().equals(
13737                                callerApp.info.packageName)) {
13738                            String msg = "Permission Denial: not allowed to send broadcast "
13739                                    + intent.getAction() + " to "
13740                                    + intent.getComponent().getPackageName() + " from "
13741                                    + callerApp.info.packageName;
13742                            Slog.w(TAG, msg);
13743                            throw new SecurityException(msg);
13744                        }
13745                    } else {
13746                        // Limit broadcast to their own package.
13747                        intent.setPackage(callerApp.info.packageName);
13748                    }
13749                }
13750            } catch (RemoteException e) {
13751                Slog.w(TAG, "Remote exception", e);
13752                return ActivityManager.BROADCAST_SUCCESS;
13753            }
13754        }
13755
13756        // Handle special intents: if this broadcast is from the package
13757        // manager about a package being removed, we need to remove all of
13758        // its activities from the history stack.
13759        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13760                intent.getAction());
13761        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13762                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13763                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13764                || uidRemoved) {
13765            if (checkComponentPermission(
13766                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13767                    callingPid, callingUid, -1, true)
13768                    == PackageManager.PERMISSION_GRANTED) {
13769                if (uidRemoved) {
13770                    final Bundle intentExtras = intent.getExtras();
13771                    final int uid = intentExtras != null
13772                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13773                    if (uid >= 0) {
13774                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13775                        synchronized (bs) {
13776                            bs.removeUidStatsLocked(uid);
13777                        }
13778                        mAppOpsService.uidRemoved(uid);
13779                    }
13780                } else {
13781                    // If resources are unavailable just force stop all
13782                    // those packages and flush the attribute cache as well.
13783                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13784                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13785                        if (list != null && (list.length > 0)) {
13786                            for (String pkg : list) {
13787                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13788                                        "storage unmount");
13789                            }
13790                            sendPackageBroadcastLocked(
13791                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13792                        }
13793                    } else {
13794                        Uri data = intent.getData();
13795                        String ssp;
13796                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13797                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13798                                    intent.getAction());
13799                            boolean fullUninstall = removed &&
13800                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13801                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13802                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13803                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13804                                        false, fullUninstall, userId,
13805                                        removed ? "pkg removed" : "pkg changed");
13806                            }
13807                            if (removed) {
13808                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13809                                        new String[] {ssp}, userId);
13810                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13811                                    mAppOpsService.packageRemoved(
13812                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13813
13814                                    // Remove all permissions granted from/to this package
13815                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13816                                }
13817                            }
13818                        }
13819                    }
13820                }
13821            } else {
13822                String msg = "Permission Denial: " + intent.getAction()
13823                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13824                        + ", uid=" + callingUid + ")"
13825                        + " requires "
13826                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13827                Slog.w(TAG, msg);
13828                throw new SecurityException(msg);
13829            }
13830
13831        // Special case for adding a package: by default turn on compatibility
13832        // mode.
13833        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13834            Uri data = intent.getData();
13835            String ssp;
13836            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13837                mCompatModePackages.handlePackageAddedLocked(ssp,
13838                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13839            }
13840        }
13841
13842        /*
13843         * If this is the time zone changed action, queue up a message that will reset the timezone
13844         * of all currently running processes. This message will get queued up before the broadcast
13845         * happens.
13846         */
13847        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13848            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13849        }
13850
13851        /*
13852         * If the user set the time, let all running processes know.
13853         */
13854        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13855            final int is24Hour = intent.getBooleanExtra(
13856                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13857            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13858        }
13859
13860        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13861            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13862        }
13863
13864        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13865            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13866            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13867        }
13868
13869        // Add to the sticky list if requested.
13870        if (sticky) {
13871            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13872                    callingPid, callingUid)
13873                    != PackageManager.PERMISSION_GRANTED) {
13874                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13875                        + callingPid + ", uid=" + callingUid
13876                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13877                Slog.w(TAG, msg);
13878                throw new SecurityException(msg);
13879            }
13880            if (requiredPermission != null) {
13881                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13882                        + " and enforce permission " + requiredPermission);
13883                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13884            }
13885            if (intent.getComponent() != null) {
13886                throw new SecurityException(
13887                        "Sticky broadcasts can't target a specific component");
13888            }
13889            // We use userId directly here, since the "all" target is maintained
13890            // as a separate set of sticky broadcasts.
13891            if (userId != UserHandle.USER_ALL) {
13892                // But first, if this is not a broadcast to all users, then
13893                // make sure it doesn't conflict with an existing broadcast to
13894                // all users.
13895                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13896                        UserHandle.USER_ALL);
13897                if (stickies != null) {
13898                    ArrayList<Intent> list = stickies.get(intent.getAction());
13899                    if (list != null) {
13900                        int N = list.size();
13901                        int i;
13902                        for (i=0; i<N; i++) {
13903                            if (intent.filterEquals(list.get(i))) {
13904                                throw new IllegalArgumentException(
13905                                        "Sticky broadcast " + intent + " for user "
13906                                        + userId + " conflicts with existing global broadcast");
13907                            }
13908                        }
13909                    }
13910                }
13911            }
13912            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13913            if (stickies == null) {
13914                stickies = new ArrayMap<String, ArrayList<Intent>>();
13915                mStickyBroadcasts.put(userId, stickies);
13916            }
13917            ArrayList<Intent> list = stickies.get(intent.getAction());
13918            if (list == null) {
13919                list = new ArrayList<Intent>();
13920                stickies.put(intent.getAction(), list);
13921            }
13922            int N = list.size();
13923            int i;
13924            for (i=0; i<N; i++) {
13925                if (intent.filterEquals(list.get(i))) {
13926                    // This sticky already exists, replace it.
13927                    list.set(i, new Intent(intent));
13928                    break;
13929                }
13930            }
13931            if (i >= N) {
13932                list.add(new Intent(intent));
13933            }
13934        }
13935
13936        int[] users;
13937        if (userId == UserHandle.USER_ALL) {
13938            // Caller wants broadcast to go to all started users.
13939            users = mStartedUserArray;
13940        } else {
13941            // Caller wants broadcast to go to one specific user.
13942            users = new int[] {userId};
13943        }
13944
13945        // Figure out who all will receive this broadcast.
13946        List receivers = null;
13947        List<BroadcastFilter> registeredReceivers = null;
13948        // Need to resolve the intent to interested receivers...
13949        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13950                 == 0) {
13951            receivers = collectReceiverComponents(intent, resolvedType, users);
13952        }
13953        if (intent.getComponent() == null) {
13954            registeredReceivers = mReceiverResolver.queryIntent(intent,
13955                    resolvedType, false, userId);
13956        }
13957
13958        final boolean replacePending =
13959                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13960
13961        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13962                + " replacePending=" + replacePending);
13963
13964        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13965        if (!ordered && NR > 0) {
13966            // If we are not serializing this broadcast, then send the
13967            // registered receivers separately so they don't wait for the
13968            // components to be launched.
13969            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13970            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13971                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13972                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13973                    ordered, sticky, false, userId);
13974            if (DEBUG_BROADCAST) Slog.v(
13975                    TAG, "Enqueueing parallel broadcast " + r);
13976            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13977            if (!replaced) {
13978                queue.enqueueParallelBroadcastLocked(r);
13979                queue.scheduleBroadcastsLocked();
13980            }
13981            registeredReceivers = null;
13982            NR = 0;
13983        }
13984
13985        // Merge into one list.
13986        int ir = 0;
13987        if (receivers != null) {
13988            // A special case for PACKAGE_ADDED: do not allow the package
13989            // being added to see this broadcast.  This prevents them from
13990            // using this as a back door to get run as soon as they are
13991            // installed.  Maybe in the future we want to have a special install
13992            // broadcast or such for apps, but we'd like to deliberately make
13993            // this decision.
13994            String skipPackages[] = null;
13995            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13996                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13997                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13998                Uri data = intent.getData();
13999                if (data != null) {
14000                    String pkgName = data.getSchemeSpecificPart();
14001                    if (pkgName != null) {
14002                        skipPackages = new String[] { pkgName };
14003                    }
14004                }
14005            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14006                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14007            }
14008            if (skipPackages != null && (skipPackages.length > 0)) {
14009                for (String skipPackage : skipPackages) {
14010                    if (skipPackage != null) {
14011                        int NT = receivers.size();
14012                        for (int it=0; it<NT; it++) {
14013                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14014                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14015                                receivers.remove(it);
14016                                it--;
14017                                NT--;
14018                            }
14019                        }
14020                    }
14021                }
14022            }
14023
14024            int NT = receivers != null ? receivers.size() : 0;
14025            int it = 0;
14026            ResolveInfo curt = null;
14027            BroadcastFilter curr = null;
14028            while (it < NT && ir < NR) {
14029                if (curt == null) {
14030                    curt = (ResolveInfo)receivers.get(it);
14031                }
14032                if (curr == null) {
14033                    curr = registeredReceivers.get(ir);
14034                }
14035                if (curr.getPriority() >= curt.priority) {
14036                    // Insert this broadcast record into the final list.
14037                    receivers.add(it, curr);
14038                    ir++;
14039                    curr = null;
14040                    it++;
14041                    NT++;
14042                } else {
14043                    // Skip to the next ResolveInfo in the final list.
14044                    it++;
14045                    curt = null;
14046                }
14047            }
14048        }
14049        while (ir < NR) {
14050            if (receivers == null) {
14051                receivers = new ArrayList();
14052            }
14053            receivers.add(registeredReceivers.get(ir));
14054            ir++;
14055        }
14056
14057        if ((receivers != null && receivers.size() > 0)
14058                || resultTo != null) {
14059            BroadcastQueue queue = broadcastQueueForIntent(intent);
14060            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14061                    callerPackage, callingPid, callingUid, resolvedType,
14062                    requiredPermission, appOp, receivers, resultTo, resultCode,
14063                    resultData, map, ordered, sticky, false, userId);
14064            if (DEBUG_BROADCAST) Slog.v(
14065                    TAG, "Enqueueing ordered broadcast " + r
14066                    + ": prev had " + queue.mOrderedBroadcasts.size());
14067            if (DEBUG_BROADCAST) {
14068                int seq = r.intent.getIntExtra("seq", -1);
14069                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14070            }
14071            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14072            if (!replaced) {
14073                queue.enqueueOrderedBroadcastLocked(r);
14074                queue.scheduleBroadcastsLocked();
14075            }
14076        }
14077
14078        return ActivityManager.BROADCAST_SUCCESS;
14079    }
14080
14081    final Intent verifyBroadcastLocked(Intent intent) {
14082        // Refuse possible leaked file descriptors
14083        if (intent != null && intent.hasFileDescriptors() == true) {
14084            throw new IllegalArgumentException("File descriptors passed in Intent");
14085        }
14086
14087        int flags = intent.getFlags();
14088
14089        if (!mProcessesReady) {
14090            // if the caller really truly claims to know what they're doing, go
14091            // ahead and allow the broadcast without launching any receivers
14092            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14093                intent = new Intent(intent);
14094                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14095            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14096                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14097                        + " before boot completion");
14098                throw new IllegalStateException("Cannot broadcast before boot completed");
14099            }
14100        }
14101
14102        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14103            throw new IllegalArgumentException(
14104                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14105        }
14106
14107        return intent;
14108    }
14109
14110    public final int broadcastIntent(IApplicationThread caller,
14111            Intent intent, String resolvedType, IIntentReceiver resultTo,
14112            int resultCode, String resultData, Bundle map,
14113            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14114        enforceNotIsolatedCaller("broadcastIntent");
14115        synchronized(this) {
14116            intent = verifyBroadcastLocked(intent);
14117
14118            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14119            final int callingPid = Binder.getCallingPid();
14120            final int callingUid = Binder.getCallingUid();
14121            final long origId = Binder.clearCallingIdentity();
14122            int res = broadcastIntentLocked(callerApp,
14123                    callerApp != null ? callerApp.info.packageName : null,
14124                    intent, resolvedType, resultTo,
14125                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14126                    callingPid, callingUid, userId);
14127            Binder.restoreCallingIdentity(origId);
14128            return res;
14129        }
14130    }
14131
14132    int broadcastIntentInPackage(String packageName, int uid,
14133            Intent intent, String resolvedType, IIntentReceiver resultTo,
14134            int resultCode, String resultData, Bundle map,
14135            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14136        synchronized(this) {
14137            intent = verifyBroadcastLocked(intent);
14138
14139            final long origId = Binder.clearCallingIdentity();
14140            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14141                    resultTo, resultCode, resultData, map, requiredPermission,
14142                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14143            Binder.restoreCallingIdentity(origId);
14144            return res;
14145        }
14146    }
14147
14148    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14149        // Refuse possible leaked file descriptors
14150        if (intent != null && intent.hasFileDescriptors() == true) {
14151            throw new IllegalArgumentException("File descriptors passed in Intent");
14152        }
14153
14154        userId = handleIncomingUser(Binder.getCallingPid(),
14155                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14156
14157        synchronized(this) {
14158            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14159                    != PackageManager.PERMISSION_GRANTED) {
14160                String msg = "Permission Denial: unbroadcastIntent() from pid="
14161                        + Binder.getCallingPid()
14162                        + ", uid=" + Binder.getCallingUid()
14163                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14164                Slog.w(TAG, msg);
14165                throw new SecurityException(msg);
14166            }
14167            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14168            if (stickies != null) {
14169                ArrayList<Intent> list = stickies.get(intent.getAction());
14170                if (list != null) {
14171                    int N = list.size();
14172                    int i;
14173                    for (i=0; i<N; i++) {
14174                        if (intent.filterEquals(list.get(i))) {
14175                            list.remove(i);
14176                            break;
14177                        }
14178                    }
14179                    if (list.size() <= 0) {
14180                        stickies.remove(intent.getAction());
14181                    }
14182                }
14183                if (stickies.size() <= 0) {
14184                    mStickyBroadcasts.remove(userId);
14185                }
14186            }
14187        }
14188    }
14189
14190    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14191            String resultData, Bundle resultExtras, boolean resultAbort) {
14192        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14193        if (r == null) {
14194            Slog.w(TAG, "finishReceiver called but not found on queue");
14195            return false;
14196        }
14197
14198        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14199    }
14200
14201    void backgroundServicesFinishedLocked(int userId) {
14202        for (BroadcastQueue queue : mBroadcastQueues) {
14203            queue.backgroundServicesFinishedLocked(userId);
14204        }
14205    }
14206
14207    public void finishReceiver(IBinder who, int resultCode, String resultData,
14208            Bundle resultExtras, boolean resultAbort) {
14209        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14210
14211        // Refuse possible leaked file descriptors
14212        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14213            throw new IllegalArgumentException("File descriptors passed in Bundle");
14214        }
14215
14216        final long origId = Binder.clearCallingIdentity();
14217        try {
14218            boolean doNext = false;
14219            BroadcastRecord r;
14220
14221            synchronized(this) {
14222                r = broadcastRecordForReceiverLocked(who);
14223                if (r != null) {
14224                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14225                        resultData, resultExtras, resultAbort, true);
14226                }
14227            }
14228
14229            if (doNext) {
14230                r.queue.processNextBroadcast(false);
14231            }
14232            trimApplications();
14233        } finally {
14234            Binder.restoreCallingIdentity(origId);
14235        }
14236    }
14237
14238    // =========================================================
14239    // INSTRUMENTATION
14240    // =========================================================
14241
14242    public boolean startInstrumentation(ComponentName className,
14243            String profileFile, int flags, Bundle arguments,
14244            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14245            int userId) {
14246        enforceNotIsolatedCaller("startInstrumentation");
14247        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14248                userId, false, true, "startInstrumentation", null);
14249        // Refuse possible leaked file descriptors
14250        if (arguments != null && arguments.hasFileDescriptors()) {
14251            throw new IllegalArgumentException("File descriptors passed in Bundle");
14252        }
14253
14254        synchronized(this) {
14255            InstrumentationInfo ii = null;
14256            ApplicationInfo ai = null;
14257            try {
14258                ii = mContext.getPackageManager().getInstrumentationInfo(
14259                    className, STOCK_PM_FLAGS);
14260                ai = AppGlobals.getPackageManager().getApplicationInfo(
14261                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14262            } catch (PackageManager.NameNotFoundException e) {
14263            } catch (RemoteException e) {
14264            }
14265            if (ii == null) {
14266                reportStartInstrumentationFailure(watcher, className,
14267                        "Unable to find instrumentation info for: " + className);
14268                return false;
14269            }
14270            if (ai == null) {
14271                reportStartInstrumentationFailure(watcher, className,
14272                        "Unable to find instrumentation target package: " + ii.targetPackage);
14273                return false;
14274            }
14275
14276            int match = mContext.getPackageManager().checkSignatures(
14277                    ii.targetPackage, ii.packageName);
14278            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14279                String msg = "Permission Denial: starting instrumentation "
14280                        + className + " from pid="
14281                        + Binder.getCallingPid()
14282                        + ", uid=" + Binder.getCallingPid()
14283                        + " not allowed because package " + ii.packageName
14284                        + " does not have a signature matching the target "
14285                        + ii.targetPackage;
14286                reportStartInstrumentationFailure(watcher, className, msg);
14287                throw new SecurityException(msg);
14288            }
14289
14290            final long origId = Binder.clearCallingIdentity();
14291            // Instrumentation can kill and relaunch even persistent processes
14292            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14293                    "start instr");
14294            ProcessRecord app = addAppLocked(ai, false);
14295            app.instrumentationClass = className;
14296            app.instrumentationInfo = ai;
14297            app.instrumentationProfileFile = profileFile;
14298            app.instrumentationArguments = arguments;
14299            app.instrumentationWatcher = watcher;
14300            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14301            app.instrumentationResultClass = className;
14302            Binder.restoreCallingIdentity(origId);
14303        }
14304
14305        return true;
14306    }
14307
14308    /**
14309     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14310     * error to the logs, but if somebody is watching, send the report there too.  This enables
14311     * the "am" command to report errors with more information.
14312     *
14313     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14314     * @param cn The component name of the instrumentation.
14315     * @param report The error report.
14316     */
14317    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14318            ComponentName cn, String report) {
14319        Slog.w(TAG, report);
14320        try {
14321            if (watcher != null) {
14322                Bundle results = new Bundle();
14323                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14324                results.putString("Error", report);
14325                watcher.instrumentationStatus(cn, -1, results);
14326            }
14327        } catch (RemoteException e) {
14328            Slog.w(TAG, e);
14329        }
14330    }
14331
14332    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14333        if (app.instrumentationWatcher != null) {
14334            try {
14335                // NOTE:  IInstrumentationWatcher *must* be oneway here
14336                app.instrumentationWatcher.instrumentationFinished(
14337                    app.instrumentationClass,
14338                    resultCode,
14339                    results);
14340            } catch (RemoteException e) {
14341            }
14342        }
14343        if (app.instrumentationUiAutomationConnection != null) {
14344            try {
14345                app.instrumentationUiAutomationConnection.shutdown();
14346            } catch (RemoteException re) {
14347                /* ignore */
14348            }
14349            // Only a UiAutomation can set this flag and now that
14350            // it is finished we make sure it is reset to its default.
14351            mUserIsMonkey = false;
14352        }
14353        app.instrumentationWatcher = null;
14354        app.instrumentationUiAutomationConnection = null;
14355        app.instrumentationClass = null;
14356        app.instrumentationInfo = null;
14357        app.instrumentationProfileFile = null;
14358        app.instrumentationArguments = null;
14359
14360        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14361                "finished inst");
14362    }
14363
14364    public void finishInstrumentation(IApplicationThread target,
14365            int resultCode, Bundle results) {
14366        int userId = UserHandle.getCallingUserId();
14367        // Refuse possible leaked file descriptors
14368        if (results != null && results.hasFileDescriptors()) {
14369            throw new IllegalArgumentException("File descriptors passed in Intent");
14370        }
14371
14372        synchronized(this) {
14373            ProcessRecord app = getRecordForAppLocked(target);
14374            if (app == null) {
14375                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14376                return;
14377            }
14378            final long origId = Binder.clearCallingIdentity();
14379            finishInstrumentationLocked(app, resultCode, results);
14380            Binder.restoreCallingIdentity(origId);
14381        }
14382    }
14383
14384    // =========================================================
14385    // CONFIGURATION
14386    // =========================================================
14387
14388    public ConfigurationInfo getDeviceConfigurationInfo() {
14389        ConfigurationInfo config = new ConfigurationInfo();
14390        synchronized (this) {
14391            config.reqTouchScreen = mConfiguration.touchscreen;
14392            config.reqKeyboardType = mConfiguration.keyboard;
14393            config.reqNavigation = mConfiguration.navigation;
14394            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14395                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14396                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14397            }
14398            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14399                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14400                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14401            }
14402            config.reqGlEsVersion = GL_ES_VERSION;
14403        }
14404        return config;
14405    }
14406
14407    ActivityStack getFocusedStack() {
14408        return mStackSupervisor.getFocusedStack();
14409    }
14410
14411    public Configuration getConfiguration() {
14412        Configuration ci;
14413        synchronized(this) {
14414            ci = new Configuration(mConfiguration);
14415        }
14416        return ci;
14417    }
14418
14419    public void updatePersistentConfiguration(Configuration values) {
14420        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14421                "updateConfiguration()");
14422        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14423                "updateConfiguration()");
14424        if (values == null) {
14425            throw new NullPointerException("Configuration must not be null");
14426        }
14427
14428        synchronized(this) {
14429            final long origId = Binder.clearCallingIdentity();
14430            updateConfigurationLocked(values, null, true, false);
14431            Binder.restoreCallingIdentity(origId);
14432        }
14433    }
14434
14435    public void updateConfiguration(Configuration values) {
14436        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14437                "updateConfiguration()");
14438
14439        synchronized(this) {
14440            if (values == null && mWindowManager != null) {
14441                // sentinel: fetch the current configuration from the window manager
14442                values = mWindowManager.computeNewConfiguration();
14443            }
14444
14445            if (mWindowManager != null) {
14446                mProcessList.applyDisplaySize(mWindowManager);
14447            }
14448
14449            final long origId = Binder.clearCallingIdentity();
14450            if (values != null) {
14451                Settings.System.clearConfiguration(values);
14452            }
14453            updateConfigurationLocked(values, null, false, false);
14454            Binder.restoreCallingIdentity(origId);
14455        }
14456    }
14457
14458    /**
14459     * Do either or both things: (1) change the current configuration, and (2)
14460     * make sure the given activity is running with the (now) current
14461     * configuration.  Returns true if the activity has been left running, or
14462     * false if <var>starting</var> is being destroyed to match the new
14463     * configuration.
14464     * @param persistent TODO
14465     */
14466    boolean updateConfigurationLocked(Configuration values,
14467            ActivityRecord starting, boolean persistent, boolean initLocale) {
14468        int changes = 0;
14469
14470        if (values != null) {
14471            Configuration newConfig = new Configuration(mConfiguration);
14472            changes = newConfig.updateFrom(values);
14473            if (changes != 0) {
14474                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14475                    Slog.i(TAG, "Updating configuration to: " + values);
14476                }
14477
14478                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14479
14480                if (values.locale != null && !initLocale) {
14481                    saveLocaleLocked(values.locale,
14482                                     !values.locale.equals(mConfiguration.locale),
14483                                     values.userSetLocale);
14484                }
14485
14486                mConfigurationSeq++;
14487                if (mConfigurationSeq <= 0) {
14488                    mConfigurationSeq = 1;
14489                }
14490                newConfig.seq = mConfigurationSeq;
14491                mConfiguration = newConfig;
14492                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14493                mUsageStatsService.noteStartConfig(newConfig);
14494
14495                final Configuration configCopy = new Configuration(mConfiguration);
14496
14497                // TODO: If our config changes, should we auto dismiss any currently
14498                // showing dialogs?
14499                mShowDialogs = shouldShowDialogs(newConfig);
14500
14501                AttributeCache ac = AttributeCache.instance();
14502                if (ac != null) {
14503                    ac.updateConfiguration(configCopy);
14504                }
14505
14506                // Make sure all resources in our process are updated
14507                // right now, so that anyone who is going to retrieve
14508                // resource values after we return will be sure to get
14509                // the new ones.  This is especially important during
14510                // boot, where the first config change needs to guarantee
14511                // all resources have that config before following boot
14512                // code is executed.
14513                mSystemThread.applyConfigurationToResources(configCopy);
14514
14515                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14516                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14517                    msg.obj = new Configuration(configCopy);
14518                    mHandler.sendMessage(msg);
14519                }
14520
14521                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14522                    ProcessRecord app = mLruProcesses.get(i);
14523                    try {
14524                        if (app.thread != null) {
14525                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14526                                    + app.processName + " new config " + mConfiguration);
14527                            app.thread.scheduleConfigurationChanged(configCopy);
14528                        }
14529                    } catch (Exception e) {
14530                    }
14531                }
14532                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14533                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14534                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14535                        | Intent.FLAG_RECEIVER_FOREGROUND);
14536                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14537                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14538                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14539                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14540                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14541                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14542                    broadcastIntentLocked(null, null, intent,
14543                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14544                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14545                }
14546            }
14547        }
14548
14549        boolean kept = true;
14550        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14551        // mainStack is null during startup.
14552        if (mainStack != null) {
14553            if (changes != 0 && starting == null) {
14554                // If the configuration changed, and the caller is not already
14555                // in the process of starting an activity, then find the top
14556                // activity to check if its configuration needs to change.
14557                starting = mainStack.topRunningActivityLocked(null);
14558            }
14559
14560            if (starting != null) {
14561                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14562                // And we need to make sure at this point that all other activities
14563                // are made visible with the correct configuration.
14564                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14565            }
14566        }
14567
14568        if (values != null && mWindowManager != null) {
14569            mWindowManager.setNewConfiguration(mConfiguration);
14570        }
14571
14572        return kept;
14573    }
14574
14575    /**
14576     * Decide based on the configuration whether we should shouw the ANR,
14577     * crash, etc dialogs.  The idea is that if there is no affordnace to
14578     * press the on-screen buttons, we shouldn't show the dialog.
14579     *
14580     * A thought: SystemUI might also want to get told about this, the Power
14581     * dialog / global actions also might want different behaviors.
14582     */
14583    private static final boolean shouldShowDialogs(Configuration config) {
14584        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14585                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14586    }
14587
14588    /**
14589     * Save the locale.  You must be inside a synchronized (this) block.
14590     */
14591    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14592        if(isDiff) {
14593            SystemProperties.set("user.language", l.getLanguage());
14594            SystemProperties.set("user.region", l.getCountry());
14595        }
14596
14597        if(isPersist) {
14598            SystemProperties.set("persist.sys.language", l.getLanguage());
14599            SystemProperties.set("persist.sys.country", l.getCountry());
14600            SystemProperties.set("persist.sys.localevar", l.getVariant());
14601        }
14602    }
14603
14604    @Override
14605    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14606        ActivityRecord srec = ActivityRecord.forToken(token);
14607        return srec != null && srec.task.affinity != null &&
14608                srec.task.affinity.equals(destAffinity);
14609    }
14610
14611    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14612            Intent resultData) {
14613
14614        synchronized (this) {
14615            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14616            if (stack != null) {
14617                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14618            }
14619            return false;
14620        }
14621    }
14622
14623    public int getLaunchedFromUid(IBinder activityToken) {
14624        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14625        if (srec == null) {
14626            return -1;
14627        }
14628        return srec.launchedFromUid;
14629    }
14630
14631    public String getLaunchedFromPackage(IBinder activityToken) {
14632        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14633        if (srec == null) {
14634            return null;
14635        }
14636        return srec.launchedFromPackage;
14637    }
14638
14639    // =========================================================
14640    // LIFETIME MANAGEMENT
14641    // =========================================================
14642
14643    // Returns which broadcast queue the app is the current [or imminent] receiver
14644    // on, or 'null' if the app is not an active broadcast recipient.
14645    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14646        BroadcastRecord r = app.curReceiver;
14647        if (r != null) {
14648            return r.queue;
14649        }
14650
14651        // It's not the current receiver, but it might be starting up to become one
14652        synchronized (this) {
14653            for (BroadcastQueue queue : mBroadcastQueues) {
14654                r = queue.mPendingBroadcast;
14655                if (r != null && r.curApp == app) {
14656                    // found it; report which queue it's in
14657                    return queue;
14658                }
14659            }
14660        }
14661
14662        return null;
14663    }
14664
14665    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14666            boolean doingAll, long now) {
14667        if (mAdjSeq == app.adjSeq) {
14668            // This adjustment has already been computed.
14669            return app.curRawAdj;
14670        }
14671
14672        if (app.thread == null) {
14673            app.adjSeq = mAdjSeq;
14674            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14675            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14676            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14677        }
14678
14679        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14680        app.adjSource = null;
14681        app.adjTarget = null;
14682        app.empty = false;
14683        app.cached = false;
14684
14685        final int activitiesSize = app.activities.size();
14686
14687        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14688            // The max adjustment doesn't allow this app to be anything
14689            // below foreground, so it is not worth doing work for it.
14690            app.adjType = "fixed";
14691            app.adjSeq = mAdjSeq;
14692            app.curRawAdj = app.maxAdj;
14693            app.foregroundActivities = false;
14694            app.keeping = true;
14695            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14696            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14697            // System processes can do UI, and when they do we want to have
14698            // them trim their memory after the user leaves the UI.  To
14699            // facilitate this, here we need to determine whether or not it
14700            // is currently showing UI.
14701            app.systemNoUi = true;
14702            if (app == TOP_APP) {
14703                app.systemNoUi = false;
14704            } else if (activitiesSize > 0) {
14705                for (int j = 0; j < activitiesSize; j++) {
14706                    final ActivityRecord r = app.activities.get(j);
14707                    if (r.visible) {
14708                        app.systemNoUi = false;
14709                    }
14710                }
14711            }
14712            if (!app.systemNoUi) {
14713                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14714            }
14715            return (app.curAdj=app.maxAdj);
14716        }
14717
14718        app.keeping = false;
14719        app.systemNoUi = false;
14720
14721        // Determine the importance of the process, starting with most
14722        // important to least, and assign an appropriate OOM adjustment.
14723        int adj;
14724        int schedGroup;
14725        int procState;
14726        boolean foregroundActivities = false;
14727        boolean interesting = false;
14728        BroadcastQueue queue;
14729        if (app == TOP_APP) {
14730            // The last app on the list is the foreground app.
14731            adj = ProcessList.FOREGROUND_APP_ADJ;
14732            schedGroup = Process.THREAD_GROUP_DEFAULT;
14733            app.adjType = "top-activity";
14734            foregroundActivities = true;
14735            interesting = true;
14736            procState = ActivityManager.PROCESS_STATE_TOP;
14737        } else if (app.instrumentationClass != null) {
14738            // Don't want to kill running instrumentation.
14739            adj = ProcessList.FOREGROUND_APP_ADJ;
14740            schedGroup = Process.THREAD_GROUP_DEFAULT;
14741            app.adjType = "instrumentation";
14742            interesting = true;
14743            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14744        } else if ((queue = isReceivingBroadcast(app)) != null) {
14745            // An app that is currently receiving a broadcast also
14746            // counts as being in the foreground for OOM killer purposes.
14747            // It's placed in a sched group based on the nature of the
14748            // broadcast as reflected by which queue it's active in.
14749            adj = ProcessList.FOREGROUND_APP_ADJ;
14750            schedGroup = (queue == mFgBroadcastQueue)
14751                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14752            app.adjType = "broadcast";
14753            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14754        } else if (app.executingServices.size() > 0) {
14755            // An app that is currently executing a service callback also
14756            // counts as being in the foreground.
14757            adj = ProcessList.FOREGROUND_APP_ADJ;
14758            schedGroup = app.execServicesFg ?
14759                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14760            app.adjType = "exec-service";
14761            procState = ActivityManager.PROCESS_STATE_SERVICE;
14762            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14763        } else {
14764            // As far as we know the process is empty.  We may change our mind later.
14765            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14766            // At this point we don't actually know the adjustment.  Use the cached adj
14767            // value that the caller wants us to.
14768            adj = cachedAdj;
14769            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14770            app.cached = true;
14771            app.empty = true;
14772            app.adjType = "cch-empty";
14773        }
14774
14775        // Examine all activities if not already foreground.
14776        if (!foregroundActivities && activitiesSize > 0) {
14777            for (int j = 0; j < activitiesSize; j++) {
14778                final ActivityRecord r = app.activities.get(j);
14779                if (r.app != app) {
14780                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14781                            + app + "?!?");
14782                    continue;
14783                }
14784                if (r.visible) {
14785                    // App has a visible activity; only upgrade adjustment.
14786                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14787                        adj = ProcessList.VISIBLE_APP_ADJ;
14788                        app.adjType = "visible";
14789                    }
14790                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14791                        procState = ActivityManager.PROCESS_STATE_TOP;
14792                    }
14793                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14794                    app.cached = false;
14795                    app.empty = false;
14796                    foregroundActivities = true;
14797                    break;
14798                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14799                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14800                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14801                        app.adjType = "pausing";
14802                    }
14803                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14804                        procState = ActivityManager.PROCESS_STATE_TOP;
14805                    }
14806                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14807                    app.cached = false;
14808                    app.empty = false;
14809                    foregroundActivities = true;
14810                } else if (r.state == ActivityState.STOPPING) {
14811                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14812                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14813                        app.adjType = "stopping";
14814                    }
14815                    // For the process state, we will at this point consider the
14816                    // process to be cached.  It will be cached either as an activity
14817                    // or empty depending on whether the activity is finishing.  We do
14818                    // this so that we can treat the process as cached for purposes of
14819                    // memory trimming (determing current memory level, trim command to
14820                    // send to process) since there can be an arbitrary number of stopping
14821                    // processes and they should soon all go into the cached state.
14822                    if (!r.finishing) {
14823                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14824                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14825                        }
14826                    }
14827                    app.cached = false;
14828                    app.empty = false;
14829                    foregroundActivities = true;
14830                } else {
14831                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14832                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14833                        app.adjType = "cch-act";
14834                    }
14835                }
14836            }
14837        }
14838
14839        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14840            if (app.foregroundServices) {
14841                // The user is aware of this app, so make it visible.
14842                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14843                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14844                app.cached = false;
14845                app.adjType = "fg-service";
14846                schedGroup = Process.THREAD_GROUP_DEFAULT;
14847            } else if (app.forcingToForeground != null) {
14848                // The user is aware of this app, so make it visible.
14849                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14850                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14851                app.cached = false;
14852                app.adjType = "force-fg";
14853                app.adjSource = app.forcingToForeground;
14854                schedGroup = Process.THREAD_GROUP_DEFAULT;
14855            }
14856        }
14857
14858        if (app.foregroundServices) {
14859            interesting = true;
14860        }
14861
14862        if (app == mHeavyWeightProcess) {
14863            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14864                // We don't want to kill the current heavy-weight process.
14865                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14866                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14867                app.cached = false;
14868                app.adjType = "heavy";
14869            }
14870            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14871                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14872            }
14873        }
14874
14875        if (app == mHomeProcess) {
14876            if (adj > ProcessList.HOME_APP_ADJ) {
14877                // This process is hosting what we currently consider to be the
14878                // home app, so we don't want to let it go into the background.
14879                adj = ProcessList.HOME_APP_ADJ;
14880                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14881                app.cached = false;
14882                app.adjType = "home";
14883            }
14884            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14885                procState = ActivityManager.PROCESS_STATE_HOME;
14886            }
14887        }
14888
14889        if (app == mPreviousProcess && app.activities.size() > 0) {
14890            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14891                // This was the previous process that showed UI to the user.
14892                // We want to try to keep it around more aggressively, to give
14893                // a good experience around switching between two apps.
14894                adj = ProcessList.PREVIOUS_APP_ADJ;
14895                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14896                app.cached = false;
14897                app.adjType = "previous";
14898            }
14899            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14900                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14901            }
14902        }
14903
14904        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14905                + " reason=" + app.adjType);
14906
14907        // By default, we use the computed adjustment.  It may be changed if
14908        // there are applications dependent on our services or providers, but
14909        // this gives us a baseline and makes sure we don't get into an
14910        // infinite recursion.
14911        app.adjSeq = mAdjSeq;
14912        app.curRawAdj = adj;
14913        app.hasStartedServices = false;
14914
14915        if (mBackupTarget != null && app == mBackupTarget.app) {
14916            // If possible we want to avoid killing apps while they're being backed up
14917            if (adj > ProcessList.BACKUP_APP_ADJ) {
14918                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14919                adj = ProcessList.BACKUP_APP_ADJ;
14920                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14921                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14922                }
14923                app.adjType = "backup";
14924                app.cached = false;
14925            }
14926            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14927                procState = ActivityManager.PROCESS_STATE_BACKUP;
14928            }
14929        }
14930
14931        boolean mayBeTop = false;
14932
14933        for (int is = app.services.size()-1;
14934                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14935                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14936                        || procState > ActivityManager.PROCESS_STATE_TOP);
14937                is--) {
14938            ServiceRecord s = app.services.valueAt(is);
14939            if (s.startRequested) {
14940                app.hasStartedServices = true;
14941                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14942                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14943                }
14944                if (app.hasShownUi && app != mHomeProcess) {
14945                    // If this process has shown some UI, let it immediately
14946                    // go to the LRU list because it may be pretty heavy with
14947                    // UI stuff.  We'll tag it with a label just to help
14948                    // debug and understand what is going on.
14949                    if (adj > ProcessList.SERVICE_ADJ) {
14950                        app.adjType = "cch-started-ui-services";
14951                    }
14952                } else {
14953                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14954                        // This service has seen some activity within
14955                        // recent memory, so we will keep its process ahead
14956                        // of the background processes.
14957                        if (adj > ProcessList.SERVICE_ADJ) {
14958                            adj = ProcessList.SERVICE_ADJ;
14959                            app.adjType = "started-services";
14960                            app.cached = false;
14961                        }
14962                    }
14963                    // If we have let the service slide into the background
14964                    // state, still have some text describing what it is doing
14965                    // even though the service no longer has an impact.
14966                    if (adj > ProcessList.SERVICE_ADJ) {
14967                        app.adjType = "cch-started-services";
14968                    }
14969                }
14970                // Don't kill this process because it is doing work; it
14971                // has said it is doing work.
14972                app.keeping = true;
14973            }
14974            for (int conni = s.connections.size()-1;
14975                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14976                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14977                            || procState > ActivityManager.PROCESS_STATE_TOP);
14978                    conni--) {
14979                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14980                for (int i = 0;
14981                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14982                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14983                                || procState > ActivityManager.PROCESS_STATE_TOP);
14984                        i++) {
14985                    // XXX should compute this based on the max of
14986                    // all connected clients.
14987                    ConnectionRecord cr = clist.get(i);
14988                    if (cr.binding.client == app) {
14989                        // Binding to ourself is not interesting.
14990                        continue;
14991                    }
14992                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14993                        ProcessRecord client = cr.binding.client;
14994                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14995                                TOP_APP, doingAll, now);
14996                        int clientProcState = client.curProcState;
14997                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14998                            // If the other app is cached for any reason, for purposes here
14999                            // we are going to consider it empty.  The specific cached state
15000                            // doesn't propagate except under certain conditions.
15001                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15002                        }
15003                        String adjType = null;
15004                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15005                            // Not doing bind OOM management, so treat
15006                            // this guy more like a started service.
15007                            if (app.hasShownUi && app != mHomeProcess) {
15008                                // If this process has shown some UI, let it immediately
15009                                // go to the LRU list because it may be pretty heavy with
15010                                // UI stuff.  We'll tag it with a label just to help
15011                                // debug and understand what is going on.
15012                                if (adj > clientAdj) {
15013                                    adjType = "cch-bound-ui-services";
15014                                }
15015                                app.cached = false;
15016                                clientAdj = adj;
15017                                clientProcState = procState;
15018                            } else {
15019                                if (now >= (s.lastActivity
15020                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15021                                    // This service has not seen activity within
15022                                    // recent memory, so allow it to drop to the
15023                                    // LRU list if there is no other reason to keep
15024                                    // it around.  We'll also tag it with a label just
15025                                    // to help debug and undertand what is going on.
15026                                    if (adj > clientAdj) {
15027                                        adjType = "cch-bound-services";
15028                                    }
15029                                    clientAdj = adj;
15030                                }
15031                            }
15032                        }
15033                        if (adj > clientAdj) {
15034                            // If this process has recently shown UI, and
15035                            // the process that is binding to it is less
15036                            // important than being visible, then we don't
15037                            // care about the binding as much as we care
15038                            // about letting this process get into the LRU
15039                            // list to be killed and restarted if needed for
15040                            // memory.
15041                            if (app.hasShownUi && app != mHomeProcess
15042                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15043                                adjType = "cch-bound-ui-services";
15044                            } else {
15045                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15046                                        |Context.BIND_IMPORTANT)) != 0) {
15047                                    adj = clientAdj;
15048                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15049                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15050                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15051                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15052                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15053                                    adj = clientAdj;
15054                                } else {
15055                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15056                                        adj = ProcessList.VISIBLE_APP_ADJ;
15057                                    }
15058                                }
15059                                if (!client.cached) {
15060                                    app.cached = false;
15061                                }
15062                                if (client.keeping) {
15063                                    app.keeping = true;
15064                                }
15065                                adjType = "service";
15066                            }
15067                        }
15068                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15069                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15070                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15071                            }
15072                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15073                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15074                                    // Special handling of clients who are in the top state.
15075                                    // We *may* want to consider this process to be in the
15076                                    // top state as well, but only if there is not another
15077                                    // reason for it to be running.  Being on the top is a
15078                                    // special state, meaning you are specifically running
15079                                    // for the current top app.  If the process is already
15080                                    // running in the background for some other reason, it
15081                                    // is more important to continue considering it to be
15082                                    // in the background state.
15083                                    mayBeTop = true;
15084                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15085                                } else {
15086                                    // Special handling for above-top states (persistent
15087                                    // processes).  These should not bring the current process
15088                                    // into the top state, since they are not on top.  Instead
15089                                    // give them the best state after that.
15090                                    clientProcState =
15091                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15092                                }
15093                            }
15094                        } else {
15095                            if (clientProcState <
15096                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15097                                clientProcState =
15098                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15099                            }
15100                        }
15101                        if (procState > clientProcState) {
15102                            procState = clientProcState;
15103                        }
15104                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15105                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15106                            app.pendingUiClean = true;
15107                        }
15108                        if (adjType != null) {
15109                            app.adjType = adjType;
15110                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15111                                    .REASON_SERVICE_IN_USE;
15112                            app.adjSource = cr.binding.client;
15113                            app.adjSourceOom = clientAdj;
15114                            app.adjTarget = s.name;
15115                        }
15116                    }
15117                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15118                        app.treatLikeActivity = true;
15119                    }
15120                    final ActivityRecord a = cr.activity;
15121                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15122                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15123                                (a.visible || a.state == ActivityState.RESUMED
15124                                 || a.state == ActivityState.PAUSING)) {
15125                            adj = ProcessList.FOREGROUND_APP_ADJ;
15126                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15127                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15128                            }
15129                            app.cached = false;
15130                            app.adjType = "service";
15131                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15132                                    .REASON_SERVICE_IN_USE;
15133                            app.adjSource = a;
15134                            app.adjSourceOom = adj;
15135                            app.adjTarget = s.name;
15136                        }
15137                    }
15138                }
15139            }
15140        }
15141
15142        for (int provi = app.pubProviders.size()-1;
15143                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15144                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15145                        || procState > ActivityManager.PROCESS_STATE_TOP);
15146                provi--) {
15147            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15148            for (int i = cpr.connections.size()-1;
15149                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15150                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15151                            || procState > ActivityManager.PROCESS_STATE_TOP);
15152                    i--) {
15153                ContentProviderConnection conn = cpr.connections.get(i);
15154                ProcessRecord client = conn.client;
15155                if (client == app) {
15156                    // Being our own client is not interesting.
15157                    continue;
15158                }
15159                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15160                int clientProcState = client.curProcState;
15161                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15162                    // If the other app is cached for any reason, for purposes here
15163                    // we are going to consider it empty.
15164                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15165                }
15166                if (adj > clientAdj) {
15167                    if (app.hasShownUi && app != mHomeProcess
15168                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15169                        app.adjType = "cch-ui-provider";
15170                    } else {
15171                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15172                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15173                        app.adjType = "provider";
15174                    }
15175                    app.cached &= client.cached;
15176                    app.keeping |= client.keeping;
15177                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15178                            .REASON_PROVIDER_IN_USE;
15179                    app.adjSource = client;
15180                    app.adjSourceOom = clientAdj;
15181                    app.adjTarget = cpr.name;
15182                }
15183                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15184                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15185                        // Special handling of clients who are in the top state.
15186                        // We *may* want to consider this process to be in the
15187                        // top state as well, but only if there is not another
15188                        // reason for it to be running.  Being on the top is a
15189                        // special state, meaning you are specifically running
15190                        // for the current top app.  If the process is already
15191                        // running in the background for some other reason, it
15192                        // is more important to continue considering it to be
15193                        // in the background state.
15194                        mayBeTop = true;
15195                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15196                    } else {
15197                        // Special handling for above-top states (persistent
15198                        // processes).  These should not bring the current process
15199                        // into the top state, since they are not on top.  Instead
15200                        // give them the best state after that.
15201                        clientProcState =
15202                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15203                    }
15204                }
15205                if (procState > clientProcState) {
15206                    procState = clientProcState;
15207                }
15208                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15209                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15210                }
15211            }
15212            // If the provider has external (non-framework) process
15213            // dependencies, ensure that its adjustment is at least
15214            // FOREGROUND_APP_ADJ.
15215            if (cpr.hasExternalProcessHandles()) {
15216                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15217                    adj = ProcessList.FOREGROUND_APP_ADJ;
15218                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15219                    app.cached = false;
15220                    app.keeping = true;
15221                    app.adjType = "provider";
15222                    app.adjTarget = cpr.name;
15223                }
15224                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15225                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15226                }
15227            }
15228        }
15229
15230        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15231            // A client of one of our services or providers is in the top state.  We
15232            // *may* want to be in the top state, but not if we are already running in
15233            // the background for some other reason.  For the decision here, we are going
15234            // to pick out a few specific states that we want to remain in when a client
15235            // is top (states that tend to be longer-term) and otherwise allow it to go
15236            // to the top state.
15237            switch (procState) {
15238                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15239                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15240                case ActivityManager.PROCESS_STATE_SERVICE:
15241                    // These all are longer-term states, so pull them up to the top
15242                    // of the background states, but not all the way to the top state.
15243                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15244                    break;
15245                default:
15246                    // Otherwise, top is a better choice, so take it.
15247                    procState = ActivityManager.PROCESS_STATE_TOP;
15248                    break;
15249            }
15250        }
15251
15252        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15253            if (app.hasClientActivities) {
15254                // This is a cached process, but with client activities.  Mark it so.
15255                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15256                app.adjType = "cch-client-act";
15257            } else if (app.treatLikeActivity) {
15258                // This is a cached process, but somebody wants us to treat it like it has
15259                // an activity, okay!
15260                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15261                app.adjType = "cch-as-act";
15262            }
15263        }
15264
15265        if (adj == ProcessList.SERVICE_ADJ) {
15266            if (doingAll) {
15267                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15268                mNewNumServiceProcs++;
15269                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15270                if (!app.serviceb) {
15271                    // This service isn't far enough down on the LRU list to
15272                    // normally be a B service, but if we are low on RAM and it
15273                    // is large we want to force it down since we would prefer to
15274                    // keep launcher over it.
15275                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15276                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15277                        app.serviceHighRam = true;
15278                        app.serviceb = true;
15279                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15280                    } else {
15281                        mNewNumAServiceProcs++;
15282                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15283                    }
15284                } else {
15285                    app.serviceHighRam = false;
15286                }
15287            }
15288            if (app.serviceb) {
15289                adj = ProcessList.SERVICE_B_ADJ;
15290            }
15291        }
15292
15293        app.curRawAdj = adj;
15294
15295        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15296        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15297        if (adj > app.maxAdj) {
15298            adj = app.maxAdj;
15299            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15300                schedGroup = Process.THREAD_GROUP_DEFAULT;
15301            }
15302        }
15303        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15304            app.keeping = true;
15305        }
15306
15307        // Do final modification to adj.  Everything we do between here and applying
15308        // the final setAdj must be done in this function, because we will also use
15309        // it when computing the final cached adj later.  Note that we don't need to
15310        // worry about this for max adj above, since max adj will always be used to
15311        // keep it out of the cached vaues.
15312        app.curAdj = app.modifyRawOomAdj(adj);
15313        app.curSchedGroup = schedGroup;
15314        app.curProcState = procState;
15315        app.foregroundActivities = foregroundActivities;
15316
15317        return app.curRawAdj;
15318    }
15319
15320    /**
15321     * Schedule PSS collection of a process.
15322     */
15323    void requestPssLocked(ProcessRecord proc, int procState) {
15324        if (mPendingPssProcesses.contains(proc)) {
15325            return;
15326        }
15327        if (mPendingPssProcesses.size() == 0) {
15328            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15329        }
15330        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15331        proc.pssProcState = procState;
15332        mPendingPssProcesses.add(proc);
15333    }
15334
15335    /**
15336     * Schedule PSS collection of all processes.
15337     */
15338    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15339        if (!always) {
15340            if (now < (mLastFullPssTime +
15341                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15342                return;
15343            }
15344        }
15345        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15346        mLastFullPssTime = now;
15347        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15348        mPendingPssProcesses.clear();
15349        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15350            ProcessRecord app = mLruProcesses.get(i);
15351            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15352                app.pssProcState = app.setProcState;
15353                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15354                        isSleeping(), now);
15355                mPendingPssProcesses.add(app);
15356            }
15357        }
15358        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15359    }
15360
15361    /**
15362     * Ask a given process to GC right now.
15363     */
15364    final void performAppGcLocked(ProcessRecord app) {
15365        try {
15366            app.lastRequestedGc = SystemClock.uptimeMillis();
15367            if (app.thread != null) {
15368                if (app.reportLowMemory) {
15369                    app.reportLowMemory = false;
15370                    app.thread.scheduleLowMemory();
15371                } else {
15372                    app.thread.processInBackground();
15373                }
15374            }
15375        } catch (Exception e) {
15376            // whatever.
15377        }
15378    }
15379
15380    /**
15381     * Returns true if things are idle enough to perform GCs.
15382     */
15383    private final boolean canGcNowLocked() {
15384        boolean processingBroadcasts = false;
15385        for (BroadcastQueue q : mBroadcastQueues) {
15386            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15387                processingBroadcasts = true;
15388            }
15389        }
15390        return !processingBroadcasts
15391                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15392    }
15393
15394    /**
15395     * Perform GCs on all processes that are waiting for it, but only
15396     * if things are idle.
15397     */
15398    final void performAppGcsLocked() {
15399        final int N = mProcessesToGc.size();
15400        if (N <= 0) {
15401            return;
15402        }
15403        if (canGcNowLocked()) {
15404            while (mProcessesToGc.size() > 0) {
15405                ProcessRecord proc = mProcessesToGc.remove(0);
15406                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15407                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15408                            <= SystemClock.uptimeMillis()) {
15409                        // To avoid spamming the system, we will GC processes one
15410                        // at a time, waiting a few seconds between each.
15411                        performAppGcLocked(proc);
15412                        scheduleAppGcsLocked();
15413                        return;
15414                    } else {
15415                        // It hasn't been long enough since we last GCed this
15416                        // process...  put it in the list to wait for its time.
15417                        addProcessToGcListLocked(proc);
15418                        break;
15419                    }
15420                }
15421            }
15422
15423            scheduleAppGcsLocked();
15424        }
15425    }
15426
15427    /**
15428     * If all looks good, perform GCs on all processes waiting for them.
15429     */
15430    final void performAppGcsIfAppropriateLocked() {
15431        if (canGcNowLocked()) {
15432            performAppGcsLocked();
15433            return;
15434        }
15435        // Still not idle, wait some more.
15436        scheduleAppGcsLocked();
15437    }
15438
15439    /**
15440     * Schedule the execution of all pending app GCs.
15441     */
15442    final void scheduleAppGcsLocked() {
15443        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15444
15445        if (mProcessesToGc.size() > 0) {
15446            // Schedule a GC for the time to the next process.
15447            ProcessRecord proc = mProcessesToGc.get(0);
15448            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15449
15450            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15451            long now = SystemClock.uptimeMillis();
15452            if (when < (now+GC_TIMEOUT)) {
15453                when = now + GC_TIMEOUT;
15454            }
15455            mHandler.sendMessageAtTime(msg, when);
15456        }
15457    }
15458
15459    /**
15460     * Add a process to the array of processes waiting to be GCed.  Keeps the
15461     * list in sorted order by the last GC time.  The process can't already be
15462     * on the list.
15463     */
15464    final void addProcessToGcListLocked(ProcessRecord proc) {
15465        boolean added = false;
15466        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15467            if (mProcessesToGc.get(i).lastRequestedGc <
15468                    proc.lastRequestedGc) {
15469                added = true;
15470                mProcessesToGc.add(i+1, proc);
15471                break;
15472            }
15473        }
15474        if (!added) {
15475            mProcessesToGc.add(0, proc);
15476        }
15477    }
15478
15479    /**
15480     * Set up to ask a process to GC itself.  This will either do it
15481     * immediately, or put it on the list of processes to gc the next
15482     * time things are idle.
15483     */
15484    final void scheduleAppGcLocked(ProcessRecord app) {
15485        long now = SystemClock.uptimeMillis();
15486        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15487            return;
15488        }
15489        if (!mProcessesToGc.contains(app)) {
15490            addProcessToGcListLocked(app);
15491            scheduleAppGcsLocked();
15492        }
15493    }
15494
15495    final void checkExcessivePowerUsageLocked(boolean doKills) {
15496        updateCpuStatsNow();
15497
15498        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15499        boolean doWakeKills = doKills;
15500        boolean doCpuKills = doKills;
15501        if (mLastPowerCheckRealtime == 0) {
15502            doWakeKills = false;
15503        }
15504        if (mLastPowerCheckUptime == 0) {
15505            doCpuKills = false;
15506        }
15507        if (stats.isScreenOn()) {
15508            doWakeKills = false;
15509        }
15510        final long curRealtime = SystemClock.elapsedRealtime();
15511        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15512        final long curUptime = SystemClock.uptimeMillis();
15513        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15514        mLastPowerCheckRealtime = curRealtime;
15515        mLastPowerCheckUptime = curUptime;
15516        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15517            doWakeKills = false;
15518        }
15519        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15520            doCpuKills = false;
15521        }
15522        int i = mLruProcesses.size();
15523        while (i > 0) {
15524            i--;
15525            ProcessRecord app = mLruProcesses.get(i);
15526            if (!app.keeping) {
15527                long wtime;
15528                synchronized (stats) {
15529                    wtime = stats.getProcessWakeTime(app.info.uid,
15530                            app.pid, curRealtime);
15531                }
15532                long wtimeUsed = wtime - app.lastWakeTime;
15533                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15534                if (DEBUG_POWER) {
15535                    StringBuilder sb = new StringBuilder(128);
15536                    sb.append("Wake for ");
15537                    app.toShortString(sb);
15538                    sb.append(": over ");
15539                    TimeUtils.formatDuration(realtimeSince, sb);
15540                    sb.append(" used ");
15541                    TimeUtils.formatDuration(wtimeUsed, sb);
15542                    sb.append(" (");
15543                    sb.append((wtimeUsed*100)/realtimeSince);
15544                    sb.append("%)");
15545                    Slog.i(TAG, sb.toString());
15546                    sb.setLength(0);
15547                    sb.append("CPU for ");
15548                    app.toShortString(sb);
15549                    sb.append(": over ");
15550                    TimeUtils.formatDuration(uptimeSince, sb);
15551                    sb.append(" used ");
15552                    TimeUtils.formatDuration(cputimeUsed, sb);
15553                    sb.append(" (");
15554                    sb.append((cputimeUsed*100)/uptimeSince);
15555                    sb.append("%)");
15556                    Slog.i(TAG, sb.toString());
15557                }
15558                // If a process has held a wake lock for more
15559                // than 50% of the time during this period,
15560                // that sounds bad.  Kill!
15561                if (doWakeKills && realtimeSince > 0
15562                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15563                    synchronized (stats) {
15564                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15565                                realtimeSince, wtimeUsed);
15566                    }
15567                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15568                            + " during " + realtimeSince);
15569                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15570                } else if (doCpuKills && uptimeSince > 0
15571                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15572                    synchronized (stats) {
15573                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15574                                uptimeSince, cputimeUsed);
15575                    }
15576                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15577                            + " during " + uptimeSince);
15578                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15579                } else {
15580                    app.lastWakeTime = wtime;
15581                    app.lastCpuTime = app.curCpuTime;
15582                }
15583            }
15584        }
15585    }
15586
15587    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15588            ProcessRecord TOP_APP, boolean doingAll, long now) {
15589        boolean success = true;
15590
15591        if (app.curRawAdj != app.setRawAdj) {
15592            if (wasKeeping && !app.keeping) {
15593                // This app is no longer something we want to keep.  Note
15594                // its current wake lock time to later know to kill it if
15595                // it is not behaving well.
15596                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15597                synchronized (stats) {
15598                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15599                            app.pid, SystemClock.elapsedRealtime());
15600                }
15601                app.lastCpuTime = app.curCpuTime;
15602            }
15603
15604            app.setRawAdj = app.curRawAdj;
15605        }
15606
15607        int changes = 0;
15608
15609        if (app.curAdj != app.setAdj) {
15610            ProcessList.setOomAdj(app.pid, app.curAdj);
15611            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15612                TAG, "Set " + app.pid + " " + app.processName +
15613                " adj " + app.curAdj + ": " + app.adjType);
15614            app.setAdj = app.curAdj;
15615        }
15616
15617        if (app.setSchedGroup != app.curSchedGroup) {
15618            app.setSchedGroup = app.curSchedGroup;
15619            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15620                    "Setting process group of " + app.processName
15621                    + " to " + app.curSchedGroup);
15622            if (app.waitingToKill != null &&
15623                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15624                killUnneededProcessLocked(app, app.waitingToKill);
15625                success = false;
15626            } else {
15627                if (true) {
15628                    long oldId = Binder.clearCallingIdentity();
15629                    try {
15630                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15631                    } catch (Exception e) {
15632                        Slog.w(TAG, "Failed setting process group of " + app.pid
15633                                + " to " + app.curSchedGroup);
15634                        e.printStackTrace();
15635                    } finally {
15636                        Binder.restoreCallingIdentity(oldId);
15637                    }
15638                } else {
15639                    if (app.thread != null) {
15640                        try {
15641                            app.thread.setSchedulingGroup(app.curSchedGroup);
15642                        } catch (RemoteException e) {
15643                        }
15644                    }
15645                }
15646                Process.setSwappiness(app.pid,
15647                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15648            }
15649        }
15650        if (app.repForegroundActivities != app.foregroundActivities) {
15651            app.repForegroundActivities = app.foregroundActivities;
15652            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15653        }
15654        if (app.repProcState != app.curProcState) {
15655            app.repProcState = app.curProcState;
15656            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15657            if (app.thread != null) {
15658                try {
15659                    if (false) {
15660                        //RuntimeException h = new RuntimeException("here");
15661                        Slog.i(TAG, "Sending new process state " + app.repProcState
15662                                + " to " + app /*, h*/);
15663                    }
15664                    app.thread.setProcessState(app.repProcState);
15665                } catch (RemoteException e) {
15666                }
15667            }
15668        }
15669        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15670                app.setProcState)) {
15671            app.lastStateTime = now;
15672            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15673                    isSleeping(), now);
15674            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15675                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15676                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15677                    + (app.nextPssTime-now) + ": " + app);
15678        } else {
15679            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15680                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15681                requestPssLocked(app, app.setProcState);
15682                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15683                        isSleeping(), now);
15684            } else if (false && DEBUG_PSS) {
15685                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15686            }
15687        }
15688        if (app.setProcState != app.curProcState) {
15689            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15690                    "Proc state change of " + app.processName
15691                    + " to " + app.curProcState);
15692            app.setProcState = app.curProcState;
15693            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15694                app.notCachedSinceIdle = false;
15695            }
15696            if (!doingAll) {
15697                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15698            } else {
15699                app.procStateChanged = true;
15700            }
15701        }
15702
15703        if (changes != 0) {
15704            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15705            int i = mPendingProcessChanges.size()-1;
15706            ProcessChangeItem item = null;
15707            while (i >= 0) {
15708                item = mPendingProcessChanges.get(i);
15709                if (item.pid == app.pid) {
15710                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15711                    break;
15712                }
15713                i--;
15714            }
15715            if (i < 0) {
15716                // No existing item in pending changes; need a new one.
15717                final int NA = mAvailProcessChanges.size();
15718                if (NA > 0) {
15719                    item = mAvailProcessChanges.remove(NA-1);
15720                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15721                } else {
15722                    item = new ProcessChangeItem();
15723                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15724                }
15725                item.changes = 0;
15726                item.pid = app.pid;
15727                item.uid = app.info.uid;
15728                if (mPendingProcessChanges.size() == 0) {
15729                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15730                            "*** Enqueueing dispatch processes changed!");
15731                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15732                }
15733                mPendingProcessChanges.add(item);
15734            }
15735            item.changes |= changes;
15736            item.processState = app.repProcState;
15737            item.foregroundActivities = app.repForegroundActivities;
15738            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15739                    + Integer.toHexString(System.identityHashCode(item))
15740                    + " " + app.toShortString() + ": changes=" + item.changes
15741                    + " procState=" + item.processState
15742                    + " foreground=" + item.foregroundActivities
15743                    + " type=" + app.adjType + " source=" + app.adjSource
15744                    + " target=" + app.adjTarget);
15745        }
15746
15747        return success;
15748    }
15749
15750    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15751        if (proc.thread != null && proc.baseProcessTracker != null) {
15752            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15753        }
15754    }
15755
15756    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15757            ProcessRecord TOP_APP, boolean doingAll, long now) {
15758        if (app.thread == null) {
15759            return false;
15760        }
15761
15762        final boolean wasKeeping = app.keeping;
15763
15764        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15765
15766        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15767    }
15768
15769    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15770            boolean oomAdj) {
15771        if (isForeground != proc.foregroundServices) {
15772            proc.foregroundServices = isForeground;
15773            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15774                    proc.info.uid);
15775            if (isForeground) {
15776                if (curProcs == null) {
15777                    curProcs = new ArrayList<ProcessRecord>();
15778                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15779                }
15780                if (!curProcs.contains(proc)) {
15781                    curProcs.add(proc);
15782                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15783                            proc.info.packageName, proc.info.uid);
15784                }
15785            } else {
15786                if (curProcs != null) {
15787                    if (curProcs.remove(proc)) {
15788                        mBatteryStatsService.noteEvent(
15789                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15790                                proc.info.packageName, proc.info.uid);
15791                        if (curProcs.size() <= 0) {
15792                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15793                        }
15794                    }
15795                }
15796            }
15797            if (oomAdj) {
15798                updateOomAdjLocked();
15799            }
15800        }
15801    }
15802
15803    private final ActivityRecord resumedAppLocked() {
15804        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15805        String pkg;
15806        int uid;
15807        if (act != null && !act.sleeping) {
15808            pkg = act.packageName;
15809            uid = act.info.applicationInfo.uid;
15810        } else {
15811            pkg = null;
15812            uid = -1;
15813        }
15814        // Has the UID or resumed package name changed?
15815        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15816                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15817            if (mCurResumedPackage != null) {
15818                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15819                        mCurResumedPackage, mCurResumedUid);
15820            }
15821            mCurResumedPackage = pkg;
15822            mCurResumedUid = uid;
15823            if (mCurResumedPackage != null) {
15824                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15825                        mCurResumedPackage, mCurResumedUid);
15826            }
15827        }
15828        return act;
15829    }
15830
15831    final boolean updateOomAdjLocked(ProcessRecord app) {
15832        final ActivityRecord TOP_ACT = resumedAppLocked();
15833        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15834        final boolean wasCached = app.cached;
15835
15836        mAdjSeq++;
15837
15838        // This is the desired cached adjusment we want to tell it to use.
15839        // If our app is currently cached, we know it, and that is it.  Otherwise,
15840        // we don't know it yet, and it needs to now be cached we will then
15841        // need to do a complete oom adj.
15842        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15843                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15844        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15845                SystemClock.uptimeMillis());
15846        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15847            // Changed to/from cached state, so apps after it in the LRU
15848            // list may also be changed.
15849            updateOomAdjLocked();
15850        }
15851        return success;
15852    }
15853
15854    final void updateOomAdjLocked() {
15855        final ActivityRecord TOP_ACT = resumedAppLocked();
15856        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15857        final long now = SystemClock.uptimeMillis();
15858        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15859        final int N = mLruProcesses.size();
15860
15861        if (false) {
15862            RuntimeException e = new RuntimeException();
15863            e.fillInStackTrace();
15864            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15865        }
15866
15867        mAdjSeq++;
15868        mNewNumServiceProcs = 0;
15869        mNewNumAServiceProcs = 0;
15870
15871        final int emptyProcessLimit;
15872        final int cachedProcessLimit;
15873        if (mProcessLimit <= 0) {
15874            emptyProcessLimit = cachedProcessLimit = 0;
15875        } else if (mProcessLimit == 1) {
15876            emptyProcessLimit = 1;
15877            cachedProcessLimit = 0;
15878        } else {
15879            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15880            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15881        }
15882
15883        // Let's determine how many processes we have running vs.
15884        // how many slots we have for background processes; we may want
15885        // to put multiple processes in a slot of there are enough of
15886        // them.
15887        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15888                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15889        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15890        if (numEmptyProcs > cachedProcessLimit) {
15891            // If there are more empty processes than our limit on cached
15892            // processes, then use the cached process limit for the factor.
15893            // This ensures that the really old empty processes get pushed
15894            // down to the bottom, so if we are running low on memory we will
15895            // have a better chance at keeping around more cached processes
15896            // instead of a gazillion empty processes.
15897            numEmptyProcs = cachedProcessLimit;
15898        }
15899        int emptyFactor = numEmptyProcs/numSlots;
15900        if (emptyFactor < 1) emptyFactor = 1;
15901        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15902        if (cachedFactor < 1) cachedFactor = 1;
15903        int stepCached = 0;
15904        int stepEmpty = 0;
15905        int numCached = 0;
15906        int numEmpty = 0;
15907        int numTrimming = 0;
15908
15909        mNumNonCachedProcs = 0;
15910        mNumCachedHiddenProcs = 0;
15911
15912        // First update the OOM adjustment for each of the
15913        // application processes based on their current state.
15914        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15915        int nextCachedAdj = curCachedAdj+1;
15916        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15917        int nextEmptyAdj = curEmptyAdj+2;
15918        for (int i=N-1; i>=0; i--) {
15919            ProcessRecord app = mLruProcesses.get(i);
15920            if (!app.killedByAm && app.thread != null) {
15921                app.procStateChanged = false;
15922                final boolean wasKeeping = app.keeping;
15923                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15924
15925                // If we haven't yet assigned the final cached adj
15926                // to the process, do that now.
15927                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15928                    switch (app.curProcState) {
15929                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15930                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15931                            // This process is a cached process holding activities...
15932                            // assign it the next cached value for that type, and then
15933                            // step that cached level.
15934                            app.curRawAdj = curCachedAdj;
15935                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15936                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15937                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15938                                    + ")");
15939                            if (curCachedAdj != nextCachedAdj) {
15940                                stepCached++;
15941                                if (stepCached >= cachedFactor) {
15942                                    stepCached = 0;
15943                                    curCachedAdj = nextCachedAdj;
15944                                    nextCachedAdj += 2;
15945                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15946                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15947                                    }
15948                                }
15949                            }
15950                            break;
15951                        default:
15952                            // For everything else, assign next empty cached process
15953                            // level and bump that up.  Note that this means that
15954                            // long-running services that have dropped down to the
15955                            // cached level will be treated as empty (since their process
15956                            // state is still as a service), which is what we want.
15957                            app.curRawAdj = curEmptyAdj;
15958                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15959                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15960                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15961                                    + ")");
15962                            if (curEmptyAdj != nextEmptyAdj) {
15963                                stepEmpty++;
15964                                if (stepEmpty >= emptyFactor) {
15965                                    stepEmpty = 0;
15966                                    curEmptyAdj = nextEmptyAdj;
15967                                    nextEmptyAdj += 2;
15968                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15969                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15970                                    }
15971                                }
15972                            }
15973                            break;
15974                    }
15975                }
15976
15977                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15978
15979                // Count the number of process types.
15980                switch (app.curProcState) {
15981                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15982                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15983                        mNumCachedHiddenProcs++;
15984                        numCached++;
15985                        if (numCached > cachedProcessLimit) {
15986                            killUnneededProcessLocked(app, "cached #" + numCached);
15987                        }
15988                        break;
15989                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15990                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15991                                && app.lastActivityTime < oldTime) {
15992                            killUnneededProcessLocked(app, "empty for "
15993                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15994                                    / 1000) + "s");
15995                        } else {
15996                            numEmpty++;
15997                            if (numEmpty > emptyProcessLimit) {
15998                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15999                            }
16000                        }
16001                        break;
16002                    default:
16003                        mNumNonCachedProcs++;
16004                        break;
16005                }
16006
16007                if (app.isolated && app.services.size() <= 0) {
16008                    // If this is an isolated process, and there are no
16009                    // services running in it, then the process is no longer
16010                    // needed.  We agressively kill these because we can by
16011                    // definition not re-use the same process again, and it is
16012                    // good to avoid having whatever code was running in them
16013                    // left sitting around after no longer needed.
16014                    killUnneededProcessLocked(app, "isolated not needed");
16015                }
16016
16017                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16018                        && !app.killedByAm) {
16019                    numTrimming++;
16020                }
16021            }
16022        }
16023
16024        mNumServiceProcs = mNewNumServiceProcs;
16025
16026        // Now determine the memory trimming level of background processes.
16027        // Unfortunately we need to start at the back of the list to do this
16028        // properly.  We only do this if the number of background apps we
16029        // are managing to keep around is less than half the maximum we desire;
16030        // if we are keeping a good number around, we'll let them use whatever
16031        // memory they want.
16032        final int numCachedAndEmpty = numCached + numEmpty;
16033        int memFactor;
16034        if (numCached <= ProcessList.TRIM_CACHED_APPS
16035                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16036            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16037                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16038            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16039                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16040            } else {
16041                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16042            }
16043        } else {
16044            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16045        }
16046        // We always allow the memory level to go up (better).  We only allow it to go
16047        // down if we are in a state where that is allowed, *and* the total number of processes
16048        // has gone down since last time.
16049        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16050                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16051                + " last=" + mLastNumProcesses);
16052        if (memFactor > mLastMemoryLevel) {
16053            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16054                memFactor = mLastMemoryLevel;
16055                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16056            }
16057        }
16058        mLastMemoryLevel = memFactor;
16059        mLastNumProcesses = mLruProcesses.size();
16060        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16061        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16062        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16063            if (mLowRamStartTime == 0) {
16064                mLowRamStartTime = now;
16065            }
16066            int step = 0;
16067            int fgTrimLevel;
16068            switch (memFactor) {
16069                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16070                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16071                    break;
16072                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16073                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16074                    break;
16075                default:
16076                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16077                    break;
16078            }
16079            int factor = numTrimming/3;
16080            int minFactor = 2;
16081            if (mHomeProcess != null) minFactor++;
16082            if (mPreviousProcess != null) minFactor++;
16083            if (factor < minFactor) factor = minFactor;
16084            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16085            for (int i=N-1; i>=0; i--) {
16086                ProcessRecord app = mLruProcesses.get(i);
16087                if (allChanged || app.procStateChanged) {
16088                    setProcessTrackerState(app, trackerMemFactor, now);
16089                    app.procStateChanged = false;
16090                }
16091                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16092                        && !app.killedByAm) {
16093                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16094                        try {
16095                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16096                                    "Trimming memory of " + app.processName
16097                                    + " to " + curLevel);
16098                            app.thread.scheduleTrimMemory(curLevel);
16099                        } catch (RemoteException e) {
16100                        }
16101                        if (false) {
16102                            // For now we won't do this; our memory trimming seems
16103                            // to be good enough at this point that destroying
16104                            // activities causes more harm than good.
16105                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16106                                    && app != mHomeProcess && app != mPreviousProcess) {
16107                                // Need to do this on its own message because the stack may not
16108                                // be in a consistent state at this point.
16109                                // For these apps we will also finish their activities
16110                                // to help them free memory.
16111                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16112                            }
16113                        }
16114                    }
16115                    app.trimMemoryLevel = curLevel;
16116                    step++;
16117                    if (step >= factor) {
16118                        step = 0;
16119                        switch (curLevel) {
16120                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16121                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16122                                break;
16123                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16124                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16125                                break;
16126                        }
16127                    }
16128                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16129                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16130                            && app.thread != null) {
16131                        try {
16132                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16133                                    "Trimming memory of heavy-weight " + app.processName
16134                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16135                            app.thread.scheduleTrimMemory(
16136                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16137                        } catch (RemoteException e) {
16138                        }
16139                    }
16140                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16141                } else {
16142                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16143                            || app.systemNoUi) && app.pendingUiClean) {
16144                        // If this application is now in the background and it
16145                        // had done UI, then give it the special trim level to
16146                        // have it free UI resources.
16147                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16148                        if (app.trimMemoryLevel < level && app.thread != null) {
16149                            try {
16150                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16151                                        "Trimming memory of bg-ui " + app.processName
16152                                        + " to " + level);
16153                                app.thread.scheduleTrimMemory(level);
16154                            } catch (RemoteException e) {
16155                            }
16156                        }
16157                        app.pendingUiClean = false;
16158                    }
16159                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16160                        try {
16161                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16162                                    "Trimming memory of fg " + app.processName
16163                                    + " to " + fgTrimLevel);
16164                            app.thread.scheduleTrimMemory(fgTrimLevel);
16165                        } catch (RemoteException e) {
16166                        }
16167                    }
16168                    app.trimMemoryLevel = fgTrimLevel;
16169                }
16170            }
16171        } else {
16172            if (mLowRamStartTime != 0) {
16173                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16174                mLowRamStartTime = 0;
16175            }
16176            for (int i=N-1; i>=0; i--) {
16177                ProcessRecord app = mLruProcesses.get(i);
16178                if (allChanged || app.procStateChanged) {
16179                    setProcessTrackerState(app, trackerMemFactor, now);
16180                    app.procStateChanged = false;
16181                }
16182                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16183                        || app.systemNoUi) && app.pendingUiClean) {
16184                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16185                            && app.thread != null) {
16186                        try {
16187                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16188                                    "Trimming memory of ui hidden " + app.processName
16189                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16190                            app.thread.scheduleTrimMemory(
16191                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16192                        } catch (RemoteException e) {
16193                        }
16194                    }
16195                    app.pendingUiClean = false;
16196                }
16197                app.trimMemoryLevel = 0;
16198            }
16199        }
16200
16201        if (mAlwaysFinishActivities) {
16202            // Need to do this on its own message because the stack may not
16203            // be in a consistent state at this point.
16204            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16205        }
16206
16207        if (allChanged) {
16208            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16209        }
16210
16211        if (mProcessStats.shouldWriteNowLocked(now)) {
16212            mHandler.post(new Runnable() {
16213                @Override public void run() {
16214                    synchronized (ActivityManagerService.this) {
16215                        mProcessStats.writeStateAsyncLocked();
16216                    }
16217                }
16218            });
16219        }
16220
16221        if (DEBUG_OOM_ADJ) {
16222            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16223        }
16224    }
16225
16226    final void trimApplications() {
16227        synchronized (this) {
16228            int i;
16229
16230            // First remove any unused application processes whose package
16231            // has been removed.
16232            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16233                final ProcessRecord app = mRemovedProcesses.get(i);
16234                if (app.activities.size() == 0
16235                        && app.curReceiver == null && app.services.size() == 0) {
16236                    Slog.i(
16237                        TAG, "Exiting empty application process "
16238                        + app.processName + " ("
16239                        + (app.thread != null ? app.thread.asBinder() : null)
16240                        + ")\n");
16241                    if (app.pid > 0 && app.pid != MY_PID) {
16242                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16243                                app.processName, app.setAdj, "empty");
16244                        app.killedByAm = true;
16245                        Process.killProcessQuiet(app.pid);
16246                    } else {
16247                        try {
16248                            app.thread.scheduleExit();
16249                        } catch (Exception e) {
16250                            // Ignore exceptions.
16251                        }
16252                    }
16253                    cleanUpApplicationRecordLocked(app, false, true, -1);
16254                    mRemovedProcesses.remove(i);
16255
16256                    if (app.persistent) {
16257                        if (app.persistent) {
16258                            addAppLocked(app.info, false);
16259                        }
16260                    }
16261                }
16262            }
16263
16264            // Now update the oom adj for all processes.
16265            updateOomAdjLocked();
16266        }
16267    }
16268
16269    /** This method sends the specified signal to each of the persistent apps */
16270    public void signalPersistentProcesses(int sig) throws RemoteException {
16271        if (sig != Process.SIGNAL_USR1) {
16272            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16273        }
16274
16275        synchronized (this) {
16276            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16277                    != PackageManager.PERMISSION_GRANTED) {
16278                throw new SecurityException("Requires permission "
16279                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16280            }
16281
16282            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16283                ProcessRecord r = mLruProcesses.get(i);
16284                if (r.thread != null && r.persistent) {
16285                    Process.sendSignal(r.pid, sig);
16286                }
16287            }
16288        }
16289    }
16290
16291    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16292        if (proc == null || proc == mProfileProc) {
16293            proc = mProfileProc;
16294            path = mProfileFile;
16295            profileType = mProfileType;
16296            clearProfilerLocked();
16297        }
16298        if (proc == null) {
16299            return;
16300        }
16301        try {
16302            proc.thread.profilerControl(false, path, null, profileType);
16303        } catch (RemoteException e) {
16304            throw new IllegalStateException("Process disappeared");
16305        }
16306    }
16307
16308    private void clearProfilerLocked() {
16309        if (mProfileFd != null) {
16310            try {
16311                mProfileFd.close();
16312            } catch (IOException e) {
16313            }
16314        }
16315        mProfileApp = null;
16316        mProfileProc = null;
16317        mProfileFile = null;
16318        mProfileType = 0;
16319        mAutoStopProfiler = false;
16320    }
16321
16322    public boolean profileControl(String process, int userId, boolean start,
16323            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16324
16325        try {
16326            synchronized (this) {
16327                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16328                // its own permission.
16329                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16330                        != PackageManager.PERMISSION_GRANTED) {
16331                    throw new SecurityException("Requires permission "
16332                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16333                }
16334
16335                if (start && fd == null) {
16336                    throw new IllegalArgumentException("null fd");
16337                }
16338
16339                ProcessRecord proc = null;
16340                if (process != null) {
16341                    proc = findProcessLocked(process, userId, "profileControl");
16342                }
16343
16344                if (start && (proc == null || proc.thread == null)) {
16345                    throw new IllegalArgumentException("Unknown process: " + process);
16346                }
16347
16348                if (start) {
16349                    stopProfilerLocked(null, null, 0);
16350                    setProfileApp(proc.info, proc.processName, path, fd, false);
16351                    mProfileProc = proc;
16352                    mProfileType = profileType;
16353                    try {
16354                        fd = fd.dup();
16355                    } catch (IOException e) {
16356                        fd = null;
16357                    }
16358                    proc.thread.profilerControl(start, path, fd, profileType);
16359                    fd = null;
16360                    mProfileFd = null;
16361                } else {
16362                    stopProfilerLocked(proc, path, profileType);
16363                    if (fd != null) {
16364                        try {
16365                            fd.close();
16366                        } catch (IOException e) {
16367                        }
16368                    }
16369                }
16370
16371                return true;
16372            }
16373        } catch (RemoteException e) {
16374            throw new IllegalStateException("Process disappeared");
16375        } finally {
16376            if (fd != null) {
16377                try {
16378                    fd.close();
16379                } catch (IOException e) {
16380                }
16381            }
16382        }
16383    }
16384
16385    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16386        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16387                userId, true, true, callName, null);
16388        ProcessRecord proc = null;
16389        try {
16390            int pid = Integer.parseInt(process);
16391            synchronized (mPidsSelfLocked) {
16392                proc = mPidsSelfLocked.get(pid);
16393            }
16394        } catch (NumberFormatException e) {
16395        }
16396
16397        if (proc == null) {
16398            ArrayMap<String, SparseArray<ProcessRecord>> all
16399                    = mProcessNames.getMap();
16400            SparseArray<ProcessRecord> procs = all.get(process);
16401            if (procs != null && procs.size() > 0) {
16402                proc = procs.valueAt(0);
16403                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16404                    for (int i=1; i<procs.size(); i++) {
16405                        ProcessRecord thisProc = procs.valueAt(i);
16406                        if (thisProc.userId == userId) {
16407                            proc = thisProc;
16408                            break;
16409                        }
16410                    }
16411                }
16412            }
16413        }
16414
16415        return proc;
16416    }
16417
16418    public boolean dumpHeap(String process, int userId, boolean managed,
16419            String path, ParcelFileDescriptor fd) throws RemoteException {
16420
16421        try {
16422            synchronized (this) {
16423                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16424                // its own permission (same as profileControl).
16425                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16426                        != PackageManager.PERMISSION_GRANTED) {
16427                    throw new SecurityException("Requires permission "
16428                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16429                }
16430
16431                if (fd == null) {
16432                    throw new IllegalArgumentException("null fd");
16433                }
16434
16435                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16436                if (proc == null || proc.thread == null) {
16437                    throw new IllegalArgumentException("Unknown process: " + process);
16438                }
16439
16440                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16441                if (!isDebuggable) {
16442                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16443                        throw new SecurityException("Process not debuggable: " + proc);
16444                    }
16445                }
16446
16447                proc.thread.dumpHeap(managed, path, fd);
16448                fd = null;
16449                return true;
16450            }
16451        } catch (RemoteException e) {
16452            throw new IllegalStateException("Process disappeared");
16453        } finally {
16454            if (fd != null) {
16455                try {
16456                    fd.close();
16457                } catch (IOException e) {
16458                }
16459            }
16460        }
16461    }
16462
16463    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16464    public void monitor() {
16465        synchronized (this) { }
16466    }
16467
16468    void onCoreSettingsChange(Bundle settings) {
16469        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16470            ProcessRecord processRecord = mLruProcesses.get(i);
16471            try {
16472                if (processRecord.thread != null) {
16473                    processRecord.thread.setCoreSettings(settings);
16474                }
16475            } catch (RemoteException re) {
16476                /* ignore */
16477            }
16478        }
16479    }
16480
16481    // Multi-user methods
16482
16483    /**
16484     * Start user, if its not already running, but don't bring it to foreground.
16485     */
16486    @Override
16487    public boolean startUserInBackground(final int userId) {
16488        return startUser(userId, /* foreground */ false);
16489    }
16490
16491    /**
16492     * Refreshes the list of users related to the current user when either a
16493     * user switch happens or when a new related user is started in the
16494     * background.
16495     */
16496    private void updateCurrentProfileIdsLocked() {
16497        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16498                mCurrentUserId, false /* enabledOnly */);
16499        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16500        for (int i = 0; i < currentProfileIds.length; i++) {
16501            currentProfileIds[i] = profiles.get(i).id;
16502        }
16503        mCurrentProfileIds = currentProfileIds;
16504    }
16505
16506    private Set getProfileIdsLocked(int userId) {
16507        Set userIds = new HashSet<Integer>();
16508        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16509                userId, false /* enabledOnly */);
16510        for (UserInfo user : profiles) {
16511            userIds.add(Integer.valueOf(user.id));
16512        }
16513        return userIds;
16514    }
16515
16516    @Override
16517    public boolean switchUser(final int userId) {
16518        return startUser(userId, /* foregound */ true);
16519    }
16520
16521    private boolean startUser(final int userId, boolean foreground) {
16522        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16523                != PackageManager.PERMISSION_GRANTED) {
16524            String msg = "Permission Denial: switchUser() from pid="
16525                    + Binder.getCallingPid()
16526                    + ", uid=" + Binder.getCallingUid()
16527                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16528            Slog.w(TAG, msg);
16529            throw new SecurityException(msg);
16530        }
16531
16532        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16533
16534        final long ident = Binder.clearCallingIdentity();
16535        try {
16536            synchronized (this) {
16537                final int oldUserId = mCurrentUserId;
16538                if (oldUserId == userId) {
16539                    return true;
16540                }
16541
16542                mStackSupervisor.setLockTaskModeLocked(null);
16543
16544                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16545                if (userInfo == null) {
16546                    Slog.w(TAG, "No user info for user #" + userId);
16547                    return false;
16548                }
16549
16550                if (foreground) {
16551                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16552                            R.anim.screen_user_enter);
16553                }
16554
16555                boolean needStart = false;
16556
16557                // If the user we are switching to is not currently started, then
16558                // we need to start it now.
16559                if (mStartedUsers.get(userId) == null) {
16560                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16561                    updateStartedUserArrayLocked();
16562                    needStart = true;
16563                }
16564
16565                final Integer userIdInt = Integer.valueOf(userId);
16566                mUserLru.remove(userIdInt);
16567                mUserLru.add(userIdInt);
16568
16569                if (foreground) {
16570                    mCurrentUserId = userId;
16571                    updateCurrentProfileIdsLocked();
16572                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16573                    // Once the internal notion of the active user has switched, we lock the device
16574                    // with the option to show the user switcher on the keyguard.
16575                    mWindowManager.lockNow(null);
16576                } else {
16577                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16578                    updateCurrentProfileIdsLocked();
16579                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16580                    mUserLru.remove(currentUserIdInt);
16581                    mUserLru.add(currentUserIdInt);
16582                }
16583
16584                final UserStartedState uss = mStartedUsers.get(userId);
16585
16586                // Make sure user is in the started state.  If it is currently
16587                // stopping, we need to knock that off.
16588                if (uss.mState == UserStartedState.STATE_STOPPING) {
16589                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16590                    // so we can just fairly silently bring the user back from
16591                    // the almost-dead.
16592                    uss.mState = UserStartedState.STATE_RUNNING;
16593                    updateStartedUserArrayLocked();
16594                    needStart = true;
16595                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16596                    // This means ACTION_SHUTDOWN has been sent, so we will
16597                    // need to treat this as a new boot of the user.
16598                    uss.mState = UserStartedState.STATE_BOOTING;
16599                    updateStartedUserArrayLocked();
16600                    needStart = true;
16601                }
16602
16603                if (uss.mState == UserStartedState.STATE_BOOTING) {
16604                    // Booting up a new user, need to tell system services about it.
16605                    // Note that this is on the same handler as scheduling of broadcasts,
16606                    // which is important because it needs to go first.
16607                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16608                }
16609
16610                if (foreground) {
16611                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16612                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16613                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16614                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16615                            oldUserId, userId, uss));
16616                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16617                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16618                }
16619
16620                if (needStart) {
16621                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16622                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16623                            | Intent.FLAG_RECEIVER_FOREGROUND);
16624                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16625                    broadcastIntentLocked(null, null, intent,
16626                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16627                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16628                }
16629
16630                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16631                    if (userId != UserHandle.USER_OWNER) {
16632                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16633                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16634                        broadcastIntentLocked(null, null, intent, null,
16635                                new IIntentReceiver.Stub() {
16636                                    public void performReceive(Intent intent, int resultCode,
16637                                            String data, Bundle extras, boolean ordered,
16638                                            boolean sticky, int sendingUser) {
16639                                        userInitialized(uss, userId);
16640                                    }
16641                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16642                                true, false, MY_PID, Process.SYSTEM_UID,
16643                                userId);
16644                        uss.initializing = true;
16645                    } else {
16646                        getUserManagerLocked().makeInitialized(userInfo.id);
16647                    }
16648                }
16649
16650                if (foreground) {
16651                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16652                    if (homeInFront) {
16653                        startHomeActivityLocked(userId);
16654                    } else {
16655                        mStackSupervisor.resumeTopActivitiesLocked();
16656                    }
16657                    EventLogTags.writeAmSwitchUser(userId);
16658                    getUserManagerLocked().userForeground(userId);
16659                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16660                } else {
16661                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16662                }
16663
16664                if (needStart) {
16665                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16666                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16667                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16668                    broadcastIntentLocked(null, null, intent,
16669                            null, new IIntentReceiver.Stub() {
16670                                @Override
16671                                public void performReceive(Intent intent, int resultCode, String data,
16672                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16673                                        throws RemoteException {
16674                                }
16675                            }, 0, null, null,
16676                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16677                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16678                }
16679            }
16680        } finally {
16681            Binder.restoreCallingIdentity(ident);
16682        }
16683
16684        return true;
16685    }
16686
16687    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16688        long ident = Binder.clearCallingIdentity();
16689        try {
16690            Intent intent;
16691            if (oldUserId >= 0) {
16692                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16693                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16694                        | Intent.FLAG_RECEIVER_FOREGROUND);
16695                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16696                broadcastIntentLocked(null, null, intent,
16697                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16698                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16699            }
16700            if (newUserId >= 0) {
16701                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16702                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16703                        | Intent.FLAG_RECEIVER_FOREGROUND);
16704                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16705                broadcastIntentLocked(null, null, intent,
16706                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16707                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16708                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16709                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16710                        | Intent.FLAG_RECEIVER_FOREGROUND);
16711                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16712                broadcastIntentLocked(null, null, intent,
16713                        null, null, 0, null, null,
16714                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16715                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16716            }
16717        } finally {
16718            Binder.restoreCallingIdentity(ident);
16719        }
16720    }
16721
16722    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16723            final int newUserId) {
16724        final int N = mUserSwitchObservers.beginBroadcast();
16725        if (N > 0) {
16726            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16727                int mCount = 0;
16728                @Override
16729                public void sendResult(Bundle data) throws RemoteException {
16730                    synchronized (ActivityManagerService.this) {
16731                        if (mCurUserSwitchCallback == this) {
16732                            mCount++;
16733                            if (mCount == N) {
16734                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16735                            }
16736                        }
16737                    }
16738                }
16739            };
16740            synchronized (this) {
16741                uss.switching = true;
16742                mCurUserSwitchCallback = callback;
16743            }
16744            for (int i=0; i<N; i++) {
16745                try {
16746                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16747                            newUserId, callback);
16748                } catch (RemoteException e) {
16749                }
16750            }
16751        } else {
16752            synchronized (this) {
16753                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16754            }
16755        }
16756        mUserSwitchObservers.finishBroadcast();
16757    }
16758
16759    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16760        synchronized (this) {
16761            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16762            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16763        }
16764    }
16765
16766    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16767        mCurUserSwitchCallback = null;
16768        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16769        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16770                oldUserId, newUserId, uss));
16771    }
16772
16773    void userInitialized(UserStartedState uss, int newUserId) {
16774        completeSwitchAndInitalize(uss, newUserId, true, false);
16775    }
16776
16777    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16778        completeSwitchAndInitalize(uss, newUserId, false, true);
16779    }
16780
16781    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16782            boolean clearInitializing, boolean clearSwitching) {
16783        boolean unfrozen = false;
16784        synchronized (this) {
16785            if (clearInitializing) {
16786                uss.initializing = false;
16787                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16788            }
16789            if (clearSwitching) {
16790                uss.switching = false;
16791            }
16792            if (!uss.switching && !uss.initializing) {
16793                mWindowManager.stopFreezingScreen();
16794                unfrozen = true;
16795            }
16796        }
16797        if (unfrozen) {
16798            final int N = mUserSwitchObservers.beginBroadcast();
16799            for (int i=0; i<N; i++) {
16800                try {
16801                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16802                } catch (RemoteException e) {
16803                }
16804            }
16805            mUserSwitchObservers.finishBroadcast();
16806        }
16807    }
16808
16809    void scheduleStartProfilesLocked() {
16810        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16811            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16812                    DateUtils.SECOND_IN_MILLIS);
16813        }
16814    }
16815
16816    void startProfilesLocked() {
16817        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16818        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16819                mCurrentUserId, false /* enabledOnly */);
16820        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16821        for (UserInfo user : profiles) {
16822            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16823                    && user.id != mCurrentUserId) {
16824                toStart.add(user);
16825            }
16826        }
16827        final int n = toStart.size();
16828        int i = 0;
16829        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16830            startUserInBackground(toStart.get(i).id);
16831        }
16832        if (i < n) {
16833            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16834        }
16835    }
16836
16837    void finishUserBoot(UserStartedState uss) {
16838        synchronized (this) {
16839            if (uss.mState == UserStartedState.STATE_BOOTING
16840                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16841                uss.mState = UserStartedState.STATE_RUNNING;
16842                final int userId = uss.mHandle.getIdentifier();
16843                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16844                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16845                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16846                broadcastIntentLocked(null, null, intent,
16847                        null, null, 0, null, null,
16848                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16849                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16850            }
16851        }
16852    }
16853
16854    void finishUserSwitch(UserStartedState uss) {
16855        synchronized (this) {
16856            finishUserBoot(uss);
16857
16858            startProfilesLocked();
16859
16860            int num = mUserLru.size();
16861            int i = 0;
16862            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16863                Integer oldUserId = mUserLru.get(i);
16864                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16865                if (oldUss == null) {
16866                    // Shouldn't happen, but be sane if it does.
16867                    mUserLru.remove(i);
16868                    num--;
16869                    continue;
16870                }
16871                if (oldUss.mState == UserStartedState.STATE_STOPPING
16872                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16873                    // This user is already stopping, doesn't count.
16874                    num--;
16875                    i++;
16876                    continue;
16877                }
16878                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16879                    // Owner and current can't be stopped, but count as running.
16880                    i++;
16881                    continue;
16882                }
16883                // This is a user to be stopped.
16884                stopUserLocked(oldUserId, null);
16885                num--;
16886                i++;
16887            }
16888        }
16889    }
16890
16891    @Override
16892    public int stopUser(final int userId, final IStopUserCallback callback) {
16893        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16894                != PackageManager.PERMISSION_GRANTED) {
16895            String msg = "Permission Denial: switchUser() from pid="
16896                    + Binder.getCallingPid()
16897                    + ", uid=" + Binder.getCallingUid()
16898                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16899            Slog.w(TAG, msg);
16900            throw new SecurityException(msg);
16901        }
16902        if (userId <= 0) {
16903            throw new IllegalArgumentException("Can't stop primary user " + userId);
16904        }
16905        synchronized (this) {
16906            return stopUserLocked(userId, callback);
16907        }
16908    }
16909
16910    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16911        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16912        if (mCurrentUserId == userId) {
16913            return ActivityManager.USER_OP_IS_CURRENT;
16914        }
16915
16916        final UserStartedState uss = mStartedUsers.get(userId);
16917        if (uss == null) {
16918            // User is not started, nothing to do...  but we do need to
16919            // callback if requested.
16920            if (callback != null) {
16921                mHandler.post(new Runnable() {
16922                    @Override
16923                    public void run() {
16924                        try {
16925                            callback.userStopped(userId);
16926                        } catch (RemoteException e) {
16927                        }
16928                    }
16929                });
16930            }
16931            return ActivityManager.USER_OP_SUCCESS;
16932        }
16933
16934        if (callback != null) {
16935            uss.mStopCallbacks.add(callback);
16936        }
16937
16938        if (uss.mState != UserStartedState.STATE_STOPPING
16939                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16940            uss.mState = UserStartedState.STATE_STOPPING;
16941            updateStartedUserArrayLocked();
16942
16943            long ident = Binder.clearCallingIdentity();
16944            try {
16945                // We are going to broadcast ACTION_USER_STOPPING and then
16946                // once that is done send a final ACTION_SHUTDOWN and then
16947                // stop the user.
16948                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16949                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16950                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16951                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16952                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16953                // This is the result receiver for the final shutdown broadcast.
16954                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16955                    @Override
16956                    public void performReceive(Intent intent, int resultCode, String data,
16957                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16958                        finishUserStop(uss);
16959                    }
16960                };
16961                // This is the result receiver for the initial stopping broadcast.
16962                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16963                    @Override
16964                    public void performReceive(Intent intent, int resultCode, String data,
16965                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16966                        // On to the next.
16967                        synchronized (ActivityManagerService.this) {
16968                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16969                                // Whoops, we are being started back up.  Abort, abort!
16970                                return;
16971                            }
16972                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16973                        }
16974                        mSystemServiceManager.stopUser(userId);
16975                        broadcastIntentLocked(null, null, shutdownIntent,
16976                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16977                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16978                    }
16979                };
16980                // Kick things off.
16981                broadcastIntentLocked(null, null, stoppingIntent,
16982                        null, stoppingReceiver, 0, null, null,
16983                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16984                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16985            } finally {
16986                Binder.restoreCallingIdentity(ident);
16987            }
16988        }
16989
16990        return ActivityManager.USER_OP_SUCCESS;
16991    }
16992
16993    void finishUserStop(UserStartedState uss) {
16994        final int userId = uss.mHandle.getIdentifier();
16995        boolean stopped;
16996        ArrayList<IStopUserCallback> callbacks;
16997        synchronized (this) {
16998            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16999            if (mStartedUsers.get(userId) != uss) {
17000                stopped = false;
17001            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17002                stopped = false;
17003            } else {
17004                stopped = true;
17005                // User can no longer run.
17006                mStartedUsers.remove(userId);
17007                mUserLru.remove(Integer.valueOf(userId));
17008                updateStartedUserArrayLocked();
17009
17010                // Clean up all state and processes associated with the user.
17011                // Kill all the processes for the user.
17012                forceStopUserLocked(userId, "finish user");
17013            }
17014        }
17015
17016        for (int i=0; i<callbacks.size(); i++) {
17017            try {
17018                if (stopped) callbacks.get(i).userStopped(userId);
17019                else callbacks.get(i).userStopAborted(userId);
17020            } catch (RemoteException e) {
17021            }
17022        }
17023
17024        if (stopped) {
17025            mSystemServiceManager.cleanupUser(userId);
17026            synchronized (this) {
17027                mStackSupervisor.removeUserLocked(userId);
17028            }
17029        }
17030    }
17031
17032    @Override
17033    public UserInfo getCurrentUser() {
17034        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17035                != PackageManager.PERMISSION_GRANTED) && (
17036                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17037                != PackageManager.PERMISSION_GRANTED)) {
17038            String msg = "Permission Denial: getCurrentUser() from pid="
17039                    + Binder.getCallingPid()
17040                    + ", uid=" + Binder.getCallingUid()
17041                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17042            Slog.w(TAG, msg);
17043            throw new SecurityException(msg);
17044        }
17045        synchronized (this) {
17046            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17047        }
17048    }
17049
17050    int getCurrentUserIdLocked() {
17051        return mCurrentUserId;
17052    }
17053
17054    @Override
17055    public boolean isUserRunning(int userId, boolean orStopped) {
17056        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17057                != PackageManager.PERMISSION_GRANTED) {
17058            String msg = "Permission Denial: isUserRunning() from pid="
17059                    + Binder.getCallingPid()
17060                    + ", uid=" + Binder.getCallingUid()
17061                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17062            Slog.w(TAG, msg);
17063            throw new SecurityException(msg);
17064        }
17065        synchronized (this) {
17066            return isUserRunningLocked(userId, orStopped);
17067        }
17068    }
17069
17070    boolean isUserRunningLocked(int userId, boolean orStopped) {
17071        UserStartedState state = mStartedUsers.get(userId);
17072        if (state == null) {
17073            return false;
17074        }
17075        if (orStopped) {
17076            return true;
17077        }
17078        return state.mState != UserStartedState.STATE_STOPPING
17079                && state.mState != UserStartedState.STATE_SHUTDOWN;
17080    }
17081
17082    @Override
17083    public int[] getRunningUserIds() {
17084        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17085                != PackageManager.PERMISSION_GRANTED) {
17086            String msg = "Permission Denial: isUserRunning() from pid="
17087                    + Binder.getCallingPid()
17088                    + ", uid=" + Binder.getCallingUid()
17089                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17090            Slog.w(TAG, msg);
17091            throw new SecurityException(msg);
17092        }
17093        synchronized (this) {
17094            return mStartedUserArray;
17095        }
17096    }
17097
17098    private void updateStartedUserArrayLocked() {
17099        int num = 0;
17100        for (int i=0; i<mStartedUsers.size();  i++) {
17101            UserStartedState uss = mStartedUsers.valueAt(i);
17102            // This list does not include stopping users.
17103            if (uss.mState != UserStartedState.STATE_STOPPING
17104                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17105                num++;
17106            }
17107        }
17108        mStartedUserArray = new int[num];
17109        num = 0;
17110        for (int i=0; i<mStartedUsers.size();  i++) {
17111            UserStartedState uss = mStartedUsers.valueAt(i);
17112            if (uss.mState != UserStartedState.STATE_STOPPING
17113                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17114                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17115                num++;
17116            }
17117        }
17118    }
17119
17120    @Override
17121    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17122        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17123                != PackageManager.PERMISSION_GRANTED) {
17124            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17125                    + Binder.getCallingPid()
17126                    + ", uid=" + Binder.getCallingUid()
17127                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17128            Slog.w(TAG, msg);
17129            throw new SecurityException(msg);
17130        }
17131
17132        mUserSwitchObservers.register(observer);
17133    }
17134
17135    @Override
17136    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17137        mUserSwitchObservers.unregister(observer);
17138    }
17139
17140    private boolean userExists(int userId) {
17141        if (userId == 0) {
17142            return true;
17143        }
17144        UserManagerService ums = getUserManagerLocked();
17145        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17146    }
17147
17148    int[] getUsersLocked() {
17149        UserManagerService ums = getUserManagerLocked();
17150        return ums != null ? ums.getUserIds() : new int[] { 0 };
17151    }
17152
17153    UserManagerService getUserManagerLocked() {
17154        if (mUserManager == null) {
17155            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17156            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17157        }
17158        return mUserManager;
17159    }
17160
17161    private int applyUserId(int uid, int userId) {
17162        return UserHandle.getUid(userId, uid);
17163    }
17164
17165    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17166        if (info == null) return null;
17167        ApplicationInfo newInfo = new ApplicationInfo(info);
17168        newInfo.uid = applyUserId(info.uid, userId);
17169        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17170                + info.packageName;
17171        return newInfo;
17172    }
17173
17174    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17175        if (aInfo == null
17176                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17177            return aInfo;
17178        }
17179
17180        ActivityInfo info = new ActivityInfo(aInfo);
17181        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17182        return info;
17183    }
17184
17185    private final class LocalService extends ActivityManagerInternal {
17186        @Override
17187        public void goingToSleep() {
17188            ActivityManagerService.this.goingToSleep();
17189        }
17190
17191        @Override
17192        public void wakingUp() {
17193            ActivityManagerService.this.wakingUp();
17194        }
17195    }
17196
17197    /**
17198     * An implementation of IAppTask, that allows an app to manage its own tasks via
17199     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17200     * only the process that calls getAppTasks() can call the AppTask methods.
17201     */
17202    class AppTaskImpl extends IAppTask.Stub {
17203        private int mTaskId;
17204        private int mCallingUid;
17205
17206        public AppTaskImpl(int taskId, int callingUid) {
17207            mTaskId = taskId;
17208            mCallingUid = callingUid;
17209        }
17210
17211        @Override
17212        public void finishAndRemoveTask() {
17213            // Ensure that we are called from the same process that created this AppTask
17214            if (mCallingUid != Binder.getCallingUid()) {
17215                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17216                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17217                return;
17218            }
17219
17220            synchronized (ActivityManagerService.this) {
17221                long origId = Binder.clearCallingIdentity();
17222                try {
17223                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17224                    if (tr != null) {
17225                        // Only kill the process if we are not a new document
17226                        int flags = tr.getBaseIntent().getFlags();
17227                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17228                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17229                        removeTaskByIdLocked(mTaskId,
17230                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17231                    }
17232                } finally {
17233                    Binder.restoreCallingIdentity(origId);
17234                }
17235            }
17236        }
17237
17238        @Override
17239        public ActivityManager.RecentTaskInfo getTaskInfo() {
17240            // Ensure that we are called from the same process that created this AppTask
17241            if (mCallingUid != Binder.getCallingUid()) {
17242                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17243                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17244                return null;
17245            }
17246
17247            synchronized (ActivityManagerService.this) {
17248                long origId = Binder.clearCallingIdentity();
17249                try {
17250                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17251                    if (tr != null) {
17252                        return createRecentTaskInfoFromTaskRecord(tr);
17253                    }
17254                } finally {
17255                    Binder.restoreCallingIdentity(origId);
17256                }
17257                return null;
17258            }
17259        }
17260    }
17261}
17262