ActivityManagerService.java revision 54eab3b35d798ce9ab061c53ac8219526132ac2d
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.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.os.UserManager;
184import android.provider.Settings;
185import android.text.format.DateUtils;
186import android.text.format.Time;
187import android.util.AtomicFile;
188import android.util.EventLog;
189import android.util.Log;
190import android.util.Pair;
191import android.util.PrintWriterPrinter;
192import android.util.Slog;
193import android.util.SparseArray;
194import android.util.TimeUtils;
195import android.util.Xml;
196import android.view.Gravity;
197import android.view.LayoutInflater;
198import android.view.View;
199import android.view.WindowManager;
200import dalvik.system.VMRuntime;
201
202import java.io.BufferedInputStream;
203import java.io.BufferedOutputStream;
204import java.io.DataInputStream;
205import java.io.DataOutputStream;
206import java.io.File;
207import java.io.FileDescriptor;
208import java.io.FileInputStream;
209import java.io.FileNotFoundException;
210import java.io.FileOutputStream;
211import java.io.IOException;
212import java.io.InputStreamReader;
213import java.io.PrintWriter;
214import java.io.StringWriter;
215import java.lang.ref.WeakReference;
216import java.util.ArrayList;
217import java.util.Arrays;
218import java.util.Collections;
219import java.util.Comparator;
220import java.util.HashMap;
221import java.util.HashSet;
222import java.util.Iterator;
223import java.util.List;
224import java.util.Locale;
225import java.util.Map;
226import java.util.Set;
227import java.util.concurrent.atomic.AtomicBoolean;
228import java.util.concurrent.atomic.AtomicLong;
229
230public final class ActivityManagerService extends ActivityManagerNative
231        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
232
233    private static final String USER_DATA_DIR = "/data/user/";
234    // File that stores last updated system version and called preboot receivers
235    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
236
237    static final String TAG = "ActivityManager";
238    static final String TAG_MU = "ActivityManagerServiceMU";
239    static final boolean DEBUG = false;
240    static final boolean localLOGV = DEBUG;
241    static final boolean DEBUG_BACKUP = localLOGV || false;
242    static final boolean DEBUG_BROADCAST = localLOGV || false;
243    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
244    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
245    static final boolean DEBUG_CLEANUP = localLOGV || false;
246    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
247    static final boolean DEBUG_FOCUS = false;
248    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
249    static final boolean DEBUG_MU = localLOGV || false;
250    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
251    static final boolean DEBUG_LRU = localLOGV || false;
252    static final boolean DEBUG_PAUSE = localLOGV || false;
253    static final boolean DEBUG_POWER = localLOGV || false;
254    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
255    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
256    static final boolean DEBUG_PROCESSES = localLOGV || false;
257    static final boolean DEBUG_PROVIDER = localLOGV || false;
258    static final boolean DEBUG_RESULTS = localLOGV || false;
259    static final boolean DEBUG_SERVICE = localLOGV || false;
260    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
261    static final boolean DEBUG_STACK = localLOGV || false;
262    static final boolean DEBUG_SWITCH = localLOGV || false;
263    static final boolean DEBUG_TASKS = localLOGV || false;
264    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
265    static final boolean DEBUG_TRANSITION = localLOGV || false;
266    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
267    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
268    static final boolean DEBUG_VISBILITY = localLOGV || false;
269    static final boolean DEBUG_PSS = localLOGV || false;
270    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
271    static final boolean DEBUG_RECENTS = localLOGV || false;
272    static final boolean VALIDATE_TOKENS = false;
273    static final boolean SHOW_ACTIVITY_START_TIME = true;
274
275    // Control over CPU and battery monitoring.
276    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
277    static final boolean MONITOR_CPU_USAGE = true;
278    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
279    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
280    static final boolean MONITOR_THREAD_CPU_USAGE = false;
281
282    // The flags that are set for all calls we make to the package manager.
283    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
284
285    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
286
287    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
288
289    // Maximum number recent bitmaps to keep in memory.
290    static final int MAX_RECENT_BITMAPS = 5;
291
292    // Amount of time after a call to stopAppSwitches() during which we will
293    // prevent further untrusted switches from happening.
294    static final long APP_SWITCH_DELAY_TIME = 5*1000;
295
296    // How long we wait for a launched process to attach to the activity manager
297    // before we decide it's never going to come up for real.
298    static final int PROC_START_TIMEOUT = 10*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real, when the process was
302    // started with a wrapper for instrumentation (such as Valgrind) because it
303    // could take much longer than usual.
304    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
305
306    // How long to wait after going idle before forcing apps to GC.
307    static final int GC_TIMEOUT = 5*1000;
308
309    // The minimum amount of time between successive GC requests for a process.
310    static final int GC_MIN_INTERVAL = 60*1000;
311
312    // The minimum amount of time between successive PSS requests for a process.
313    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process
316    // when the request is due to the memory state being lowered.
317    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
318
319    // The rate at which we check for apps using excessive power -- 15 mins.
320    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
321
322    // The minimum sample duration we will allow before deciding we have
323    // enough data on wake locks to start killing things.
324    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on CPU usage to start killing things.
328    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // How long we allow a receiver to run before giving up on it.
331    static final int BROADCAST_FG_TIMEOUT = 10*1000;
332    static final int BROADCAST_BG_TIMEOUT = 60*1000;
333
334    // How long we wait until we timeout on key dispatching.
335    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
336
337    // How long we wait until we timeout on key dispatching during instrumentation.
338    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
339
340    // Amount of time we wait for observers to handle a user switch before
341    // giving up on them and unfreezing the screen.
342    static final int USER_SWITCH_TIMEOUT = 2*1000;
343
344    // Maximum number of users we allow to be running at a time.
345    static final int MAX_RUNNING_USERS = 3;
346
347    // How long to wait in getAssistContextExtras for the activity and foreground services
348    // to respond with the result.
349    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
350
351    // Maximum number of persisted Uri grants a package is allowed
352    static final int MAX_PERSISTED_URI_GRANTS = 128;
353
354    static final int MY_PID = Process.myPid();
355
356    static final String[] EMPTY_STRING_ARRAY = new String[0];
357
358    // How many bytes to write into the dropbox log before truncating
359    static final int DROPBOX_MAX_SIZE = 256 * 1024;
360
361    // Access modes for handleIncomingUser.
362    static final int ALLOW_NON_FULL = 0;
363    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
364    static final int ALLOW_FULL_ONLY = 2;
365
366    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
367
368    /** All system services */
369    SystemServiceManager mSystemServiceManager;
370
371    /** Run all ActivityStacks through this */
372    ActivityStackSupervisor mStackSupervisor;
373
374    public IntentFirewall mIntentFirewall;
375
376    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
377    // default actuion automatically.  Important for devices without direct input
378    // devices.
379    private boolean mShowDialogs = true;
380
381    BroadcastQueue mFgBroadcastQueue;
382    BroadcastQueue mBgBroadcastQueue;
383    // Convenient for easy iteration over the queues. Foreground is first
384    // so that dispatch of foreground broadcasts gets precedence.
385    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
386
387    BroadcastQueue broadcastQueueForIntent(Intent intent) {
388        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
389        if (DEBUG_BACKGROUND_BROADCAST) {
390            Slog.i(TAG, "Broadcast intent " + intent + " on "
391                    + (isFg ? "foreground" : "background")
392                    + " queue");
393        }
394        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
395    }
396
397    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
398        for (BroadcastQueue queue : mBroadcastQueues) {
399            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
400            if (r != null) {
401                return r;
402            }
403        }
404        return null;
405    }
406
407    /**
408     * Activity we have told the window manager to have key focus.
409     */
410    ActivityRecord mFocusedActivity = null;
411
412    /**
413     * List of intents that were used to start the most recent tasks.
414     */
415    ArrayList<TaskRecord> mRecentTasks;
416    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
417
418    /**
419     * For addAppTask: cached of the last activity component that was added.
420     */
421    ComponentName mLastAddedTaskComponent;
422
423    /**
424     * For addAppTask: cached of the last activity uid that was added.
425     */
426    int mLastAddedTaskUid;
427
428    /**
429     * For addAppTask: cached of the last ActivityInfo that was added.
430     */
431    ActivityInfo mLastAddedTaskActivity;
432
433    public class PendingAssistExtras extends Binder implements Runnable {
434        public final ActivityRecord activity;
435        public boolean haveResult = false;
436        public Bundle result = null;
437        public PendingAssistExtras(ActivityRecord _activity) {
438            activity = _activity;
439        }
440        @Override
441        public void run() {
442            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
443            synchronized (this) {
444                haveResult = true;
445                notifyAll();
446            }
447        }
448    }
449
450    final ArrayList<PendingAssistExtras> mPendingAssistExtras
451            = new ArrayList<PendingAssistExtras>();
452
453    /**
454     * Process management.
455     */
456    final ProcessList mProcessList = new ProcessList();
457
458    /**
459     * All of the applications we currently have running organized by name.
460     * The keys are strings of the application package name (as
461     * returned by the package manager), and the keys are ApplicationRecord
462     * objects.
463     */
464    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
465
466    /**
467     * Tracking long-term execution of processes to look for abuse and other
468     * bad app behavior.
469     */
470    final ProcessStatsService mProcessStats;
471
472    /**
473     * The currently running isolated processes.
474     */
475    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
476
477    /**
478     * Counter for assigning isolated process uids, to avoid frequently reusing the
479     * same ones.
480     */
481    int mNextIsolatedProcessUid = 0;
482
483    /**
484     * The currently running heavy-weight process, if any.
485     */
486    ProcessRecord mHeavyWeightProcess = null;
487
488    /**
489     * The last time that various processes have crashed.
490     */
491    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
492
493    /**
494     * Information about a process that is currently marked as bad.
495     */
496    static final class BadProcessInfo {
497        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
498            this.time = time;
499            this.shortMsg = shortMsg;
500            this.longMsg = longMsg;
501            this.stack = stack;
502        }
503
504        final long time;
505        final String shortMsg;
506        final String longMsg;
507        final String stack;
508    }
509
510    /**
511     * Set of applications that we consider to be bad, and will reject
512     * incoming broadcasts from (which the user has no control over).
513     * Processes are added to this set when they have crashed twice within
514     * a minimum amount of time; they are removed from it when they are
515     * later restarted (hopefully due to some user action).  The value is the
516     * time it was added to the list.
517     */
518    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
519
520    /**
521     * All of the processes we currently have running organized by pid.
522     * The keys are the pid running the application.
523     *
524     * <p>NOTE: This object is protected by its own lock, NOT the global
525     * activity manager lock!
526     */
527    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
528
529    /**
530     * All of the processes that have been forced to be foreground.  The key
531     * is the pid of the caller who requested it (we hold a death
532     * link on it).
533     */
534    abstract class ForegroundToken implements IBinder.DeathRecipient {
535        int pid;
536        IBinder token;
537    }
538    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
539
540    /**
541     * List of records for processes that someone had tried to start before the
542     * system was ready.  We don't start them at that point, but ensure they
543     * are started by the time booting is complete.
544     */
545    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
546
547    /**
548     * List of persistent applications that are in the process
549     * of being started.
550     */
551    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Processes that are being forcibly torn down.
555     */
556    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of running applications, sorted by recent usage.
560     * The first entry in the list is the least recently used.
561     */
562    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Where in mLruProcesses that the processes hosting activities start.
566     */
567    int mLruProcessActivityStart = 0;
568
569    /**
570     * Where in mLruProcesses that the processes hosting services start.
571     * This is after (lower index) than mLruProcessesActivityStart.
572     */
573    int mLruProcessServiceStart = 0;
574
575    /**
576     * List of processes that should gc as soon as things are idle.
577     */
578    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
579
580    /**
581     * Processes we want to collect PSS data from.
582     */
583    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
584
585    /**
586     * Last time we requested PSS data of all processes.
587     */
588    long mLastFullPssTime = SystemClock.uptimeMillis();
589
590    /**
591     * If set, the next time we collect PSS data we should do a full collection
592     * with data from native processes and the kernel.
593     */
594    boolean mFullPssPending = false;
595
596    /**
597     * This is the process holding what we currently consider to be
598     * the "home" activity.
599     */
600    ProcessRecord mHomeProcess;
601
602    /**
603     * This is the process holding the activity the user last visited that
604     * is in a different process from the one they are currently in.
605     */
606    ProcessRecord mPreviousProcess;
607
608    /**
609     * The time at which the previous process was last visible.
610     */
611    long mPreviousProcessVisibleTime;
612
613    /**
614     * Which uses have been started, so are allowed to run code.
615     */
616    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
617
618    /**
619     * LRU list of history of current users.  Most recently current is at the end.
620     */
621    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
622
623    /**
624     * Constant array of the users that are currently started.
625     */
626    int[] mStartedUserArray = new int[] { 0 };
627
628    /**
629     * Registered observers of the user switching mechanics.
630     */
631    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
632            = new RemoteCallbackList<IUserSwitchObserver>();
633
634    /**
635     * Currently active user switch.
636     */
637    Object mCurUserSwitchCallback;
638
639    /**
640     * Packages that the user has asked to have run in screen size
641     * compatibility mode instead of filling the screen.
642     */
643    final CompatModePackages mCompatModePackages;
644
645    /**
646     * Set of IntentSenderRecord objects that are currently active.
647     */
648    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
649            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
650
651    /**
652     * Fingerprints (hashCode()) of stack traces that we've
653     * already logged DropBox entries for.  Guarded by itself.  If
654     * something (rogue user app) forces this over
655     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
656     */
657    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
658    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
659
660    /**
661     * Strict Mode background batched logging state.
662     *
663     * The string buffer is guarded by itself, and its lock is also
664     * used to determine if another batched write is already
665     * in-flight.
666     */
667    private final StringBuilder mStrictModeBuffer = new StringBuilder();
668
669    /**
670     * Keeps track of all IIntentReceivers that have been registered for
671     * broadcasts.  Hash keys are the receiver IBinder, hash value is
672     * a ReceiverList.
673     */
674    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
675            new HashMap<IBinder, ReceiverList>();
676
677    /**
678     * Resolver for broadcast intents to registered receivers.
679     * Holds BroadcastFilter (subclass of IntentFilter).
680     */
681    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
682            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
683        @Override
684        protected boolean allowFilterResult(
685                BroadcastFilter filter, List<BroadcastFilter> dest) {
686            IBinder target = filter.receiverList.receiver.asBinder();
687            for (int i=dest.size()-1; i>=0; i--) {
688                if (dest.get(i).receiverList.receiver.asBinder() == target) {
689                    return false;
690                }
691            }
692            return true;
693        }
694
695        @Override
696        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
697            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
698                    || userId == filter.owningUserId) {
699                return super.newResult(filter, match, userId);
700            }
701            return null;
702        }
703
704        @Override
705        protected BroadcastFilter[] newArray(int size) {
706            return new BroadcastFilter[size];
707        }
708
709        @Override
710        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
711            return packageName.equals(filter.packageName);
712        }
713    };
714
715    /**
716     * State of all active sticky broadcasts per user.  Keys are the action of the
717     * sticky Intent, values are an ArrayList of all broadcasted intents with
718     * that action (which should usually be one).  The SparseArray is keyed
719     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
720     * for stickies that are sent to all users.
721     */
722    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
723            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
724
725    final ActiveServices mServices;
726
727    /**
728     * Backup/restore process management
729     */
730    String mBackupAppName = null;
731    BackupRecord mBackupTarget = null;
732
733    final ProviderMap mProviderMap;
734
735    /**
736     * List of content providers who have clients waiting for them.  The
737     * application is currently being launched and the provider will be
738     * removed from this list once it is published.
739     */
740    final ArrayList<ContentProviderRecord> mLaunchingProviders
741            = new ArrayList<ContentProviderRecord>();
742
743    /**
744     * File storing persisted {@link #mGrantedUriPermissions}.
745     */
746    private final AtomicFile mGrantFile;
747
748    /** XML constants used in {@link #mGrantFile} */
749    private static final String TAG_URI_GRANTS = "uri-grants";
750    private static final String TAG_URI_GRANT = "uri-grant";
751    private static final String ATTR_USER_HANDLE = "userHandle";
752    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
753    private static final String ATTR_TARGET_USER_ID = "targetUserId";
754    private static final String ATTR_SOURCE_PKG = "sourcePkg";
755    private static final String ATTR_TARGET_PKG = "targetPkg";
756    private static final String ATTR_URI = "uri";
757    private static final String ATTR_MODE_FLAGS = "modeFlags";
758    private static final String ATTR_CREATED_TIME = "createdTime";
759    private static final String ATTR_PREFIX = "prefix";
760
761    /**
762     * Global set of specific {@link Uri} permissions that have been granted.
763     * This optimized lookup structure maps from {@link UriPermission#targetUid}
764     * to {@link UriPermission#uri} to {@link UriPermission}.
765     */
766    @GuardedBy("this")
767    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
768            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
769
770    public static class GrantUri {
771        public final int sourceUserId;
772        public final Uri uri;
773        public boolean prefix;
774
775        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
776            this.sourceUserId = sourceUserId;
777            this.uri = uri;
778            this.prefix = prefix;
779        }
780
781        @Override
782        public int hashCode() {
783            return toString().hashCode();
784        }
785
786        @Override
787        public boolean equals(Object o) {
788            if (o instanceof GrantUri) {
789                GrantUri other = (GrantUri) o;
790                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
791                        && prefix == other.prefix;
792            }
793            return false;
794        }
795
796        @Override
797        public String toString() {
798            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
799            if (prefix) result += " [prefix]";
800            return result;
801        }
802
803        public String toSafeString() {
804            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
805            if (prefix) result += " [prefix]";
806            return result;
807        }
808
809        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
810            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
811                    ContentProvider.getUriWithoutUserId(uri), false);
812        }
813    }
814
815    CoreSettingsObserver mCoreSettingsObserver;
816
817    /**
818     * Thread-local storage used to carry caller permissions over through
819     * indirect content-provider access.
820     */
821    private class Identity {
822        public int pid;
823        public int uid;
824
825        Identity(int _pid, int _uid) {
826            pid = _pid;
827            uid = _uid;
828        }
829    }
830
831    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
832
833    /**
834     * All information we have collected about the runtime performance of
835     * any user id that can impact battery performance.
836     */
837    final BatteryStatsService mBatteryStatsService;
838
839    /**
840     * Information about component usage
841     */
842    UsageStatsManagerInternal mUsageStatsService;
843
844    /**
845     * Information about and control over application operations
846     */
847    final AppOpsService mAppOpsService;
848
849    /**
850     * Save recent tasks information across reboots.
851     */
852    final TaskPersister mTaskPersister;
853
854    /**
855     * Current configuration information.  HistoryRecord objects are given
856     * a reference to this object to indicate which configuration they are
857     * currently running in, so this object must be kept immutable.
858     */
859    Configuration mConfiguration = new Configuration();
860
861    /**
862     * Current sequencing integer of the configuration, for skipping old
863     * configurations.
864     */
865    int mConfigurationSeq = 0;
866
867    /**
868     * Hardware-reported OpenGLES version.
869     */
870    final int GL_ES_VERSION;
871
872    /**
873     * List of initialization arguments to pass to all processes when binding applications to them.
874     * For example, references to the commonly used services.
875     */
876    HashMap<String, IBinder> mAppBindArgs;
877
878    /**
879     * Temporary to avoid allocations.  Protected by main lock.
880     */
881    final StringBuilder mStringBuilder = new StringBuilder(256);
882
883    /**
884     * Used to control how we initialize the service.
885     */
886    ComponentName mTopComponent;
887    String mTopAction = Intent.ACTION_MAIN;
888    String mTopData;
889    boolean mProcessesReady = false;
890    boolean mSystemReady = false;
891    boolean mBooting = false;
892    boolean mCallFinishBooting = false;
893    boolean mBootAnimationComplete = false;
894    boolean mWaitingUpdate = false;
895    boolean mDidUpdate = false;
896    boolean mOnBattery = false;
897    boolean mLaunchWarningShown = false;
898
899    Context mContext;
900
901    int mFactoryTest;
902
903    boolean mCheckedForSetup;
904
905    /**
906     * The time at which we will allow normal application switches again,
907     * after a call to {@link #stopAppSwitches()}.
908     */
909    long mAppSwitchesAllowedTime;
910
911    /**
912     * This is set to true after the first switch after mAppSwitchesAllowedTime
913     * is set; any switches after that will clear the time.
914     */
915    boolean mDidAppSwitch;
916
917    /**
918     * Last time (in realtime) at which we checked for power usage.
919     */
920    long mLastPowerCheckRealtime;
921
922    /**
923     * Last time (in uptime) at which we checked for power usage.
924     */
925    long mLastPowerCheckUptime;
926
927    /**
928     * Set while we are wanting to sleep, to prevent any
929     * activities from being started/resumed.
930     */
931    private boolean mSleeping = false;
932
933    /**
934     * Set while we are running a voice interaction.  This overrides
935     * sleeping while it is active.
936     */
937    private boolean mRunningVoice = false;
938
939    /**
940     * Set while the keyguard is waiting for an activity to draw.
941     * In this state, if we are sleeping, we allow Activities to launch
942     * so that they can draw before Keyguard dismisses itself.
943     */
944    private boolean mKeyguardWaitingForDraw = false;
945
946    /**
947     * State of external calls telling us if the device is asleep.
948     */
949    private boolean mWentToSleep = false;
950
951    /**
952     * State of external call telling us if the lock screen is shown.
953     */
954    private boolean mLockScreenShown = false;
955
956    /**
957     * Set if we are shutting down the system, similar to sleeping.
958     */
959    boolean mShuttingDown = false;
960
961    /**
962     * Current sequence id for oom_adj computation traversal.
963     */
964    int mAdjSeq = 0;
965
966    /**
967     * Current sequence id for process LRU updating.
968     */
969    int mLruSeq = 0;
970
971    /**
972     * Keep track of the non-cached/empty process we last found, to help
973     * determine how to distribute cached/empty processes next time.
974     */
975    int mNumNonCachedProcs = 0;
976
977    /**
978     * Keep track of the number of cached hidden procs, to balance oom adj
979     * distribution between those and empty procs.
980     */
981    int mNumCachedHiddenProcs = 0;
982
983    /**
984     * Keep track of the number of service processes we last found, to
985     * determine on the next iteration which should be B services.
986     */
987    int mNumServiceProcs = 0;
988    int mNewNumAServiceProcs = 0;
989    int mNewNumServiceProcs = 0;
990
991    /**
992     * Allow the current computed overall memory level of the system to go down?
993     * This is set to false when we are killing processes for reasons other than
994     * memory management, so that the now smaller process list will not be taken as
995     * an indication that memory is tighter.
996     */
997    boolean mAllowLowerMemLevel = false;
998
999    /**
1000     * The last computed memory level, for holding when we are in a state that
1001     * processes are going away for other reasons.
1002     */
1003    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1004
1005    /**
1006     * The last total number of process we have, to determine if changes actually look
1007     * like a shrinking number of process due to lower RAM.
1008     */
1009    int mLastNumProcesses;
1010
1011    /**
1012     * The uptime of the last time we performed idle maintenance.
1013     */
1014    long mLastIdleTime = SystemClock.uptimeMillis();
1015
1016    /**
1017     * Total time spent with RAM that has been added in the past since the last idle time.
1018     */
1019    long mLowRamTimeSinceLastIdle = 0;
1020
1021    /**
1022     * If RAM is currently low, when that horrible situation started.
1023     */
1024    long mLowRamStartTime = 0;
1025
1026    /**
1027     * For reporting to battery stats the current top application.
1028     */
1029    private String mCurResumedPackage = null;
1030    private int mCurResumedUid = -1;
1031
1032    /**
1033     * For reporting to battery stats the apps currently running foreground
1034     * service.  The ProcessMap is package/uid tuples; each of these contain
1035     * an array of the currently foreground processes.
1036     */
1037    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1038            = new ProcessMap<ArrayList<ProcessRecord>>();
1039
1040    /**
1041     * This is set if we had to do a delayed dexopt of an app before launching
1042     * it, to increase the ANR timeouts in that case.
1043     */
1044    boolean mDidDexOpt;
1045
1046    /**
1047     * Set if the systemServer made a call to enterSafeMode.
1048     */
1049    boolean mSafeMode;
1050
1051    String mDebugApp = null;
1052    boolean mWaitForDebugger = false;
1053    boolean mDebugTransient = false;
1054    String mOrigDebugApp = null;
1055    boolean mOrigWaitForDebugger = false;
1056    boolean mAlwaysFinishActivities = false;
1057    IActivityController mController = null;
1058    String mProfileApp = null;
1059    ProcessRecord mProfileProc = null;
1060    String mProfileFile;
1061    ParcelFileDescriptor mProfileFd;
1062    int mSamplingInterval = 0;
1063    boolean mAutoStopProfiler = false;
1064    int mProfileType = 0;
1065    String mOpenGlTraceApp = null;
1066
1067    static class ProcessChangeItem {
1068        static final int CHANGE_ACTIVITIES = 1<<0;
1069        static final int CHANGE_PROCESS_STATE = 1<<1;
1070        int changes;
1071        int uid;
1072        int pid;
1073        int processState;
1074        boolean foregroundActivities;
1075    }
1076
1077    final RemoteCallbackList<IProcessObserver> mProcessObservers
1078            = new RemoteCallbackList<IProcessObserver>();
1079    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1080
1081    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1082            = new ArrayList<ProcessChangeItem>();
1083    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1084            = new ArrayList<ProcessChangeItem>();
1085
1086    /**
1087     * Runtime CPU use collection thread.  This object's lock is used to
1088     * perform synchronization with the thread (notifying it to run).
1089     */
1090    final Thread mProcessCpuThread;
1091
1092    /**
1093     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1094     * Must acquire this object's lock when accessing it.
1095     * NOTE: this lock will be held while doing long operations (trawling
1096     * through all processes in /proc), so it should never be acquired by
1097     * any critical paths such as when holding the main activity manager lock.
1098     */
1099    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1100            MONITOR_THREAD_CPU_USAGE);
1101    final AtomicLong mLastCpuTime = new AtomicLong(0);
1102    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1103
1104    long mLastWriteTime = 0;
1105
1106    /**
1107     * Used to retain an update lock when the foreground activity is in
1108     * immersive mode.
1109     */
1110    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1111
1112    /**
1113     * Set to true after the system has finished booting.
1114     */
1115    boolean mBooted = false;
1116
1117    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1118    int mProcessLimitOverride = -1;
1119
1120    WindowManagerService mWindowManager;
1121
1122    final ActivityThread mSystemThread;
1123
1124    // Holds the current foreground user's id
1125    int mCurrentUserId = 0;
1126    // Holds the target user's id during a user switch
1127    int mTargetUserId = UserHandle.USER_NULL;
1128    // If there are multiple profiles for the current user, their ids are here
1129    // Currently only the primary user can have managed profiles
1130    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1131
1132    /**
1133     * Mapping from each known user ID to the profile group ID it is associated with.
1134     */
1135    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1136
1137    private UserManagerService mUserManager;
1138
1139    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1140        final ProcessRecord mApp;
1141        final int mPid;
1142        final IApplicationThread mAppThread;
1143
1144        AppDeathRecipient(ProcessRecord app, int pid,
1145                IApplicationThread thread) {
1146            if (localLOGV) Slog.v(
1147                TAG, "New death recipient " + this
1148                + " for thread " + thread.asBinder());
1149            mApp = app;
1150            mPid = pid;
1151            mAppThread = thread;
1152        }
1153
1154        @Override
1155        public void binderDied() {
1156            if (localLOGV) Slog.v(
1157                TAG, "Death received in " + this
1158                + " for thread " + mAppThread.asBinder());
1159            synchronized(ActivityManagerService.this) {
1160                appDiedLocked(mApp, mPid, mAppThread);
1161            }
1162        }
1163    }
1164
1165    static final int SHOW_ERROR_MSG = 1;
1166    static final int SHOW_NOT_RESPONDING_MSG = 2;
1167    static final int SHOW_FACTORY_ERROR_MSG = 3;
1168    static final int UPDATE_CONFIGURATION_MSG = 4;
1169    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1170    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1171    static final int SERVICE_TIMEOUT_MSG = 12;
1172    static final int UPDATE_TIME_ZONE = 13;
1173    static final int SHOW_UID_ERROR_MSG = 14;
1174    static final int IM_FEELING_LUCKY_MSG = 15;
1175    static final int PROC_START_TIMEOUT_MSG = 20;
1176    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1177    static final int KILL_APPLICATION_MSG = 22;
1178    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1179    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1180    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1181    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1182    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1183    static final int CLEAR_DNS_CACHE_MSG = 28;
1184    static final int UPDATE_HTTP_PROXY_MSG = 29;
1185    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1186    static final int DISPATCH_PROCESSES_CHANGED = 31;
1187    static final int DISPATCH_PROCESS_DIED = 32;
1188    static final int REPORT_MEM_USAGE_MSG = 33;
1189    static final int REPORT_USER_SWITCH_MSG = 34;
1190    static final int CONTINUE_USER_SWITCH_MSG = 35;
1191    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1192    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1193    static final int PERSIST_URI_GRANTS_MSG = 38;
1194    static final int REQUEST_ALL_PSS_MSG = 39;
1195    static final int START_PROFILES_MSG = 40;
1196    static final int UPDATE_TIME = 41;
1197    static final int SYSTEM_USER_START_MSG = 42;
1198    static final int SYSTEM_USER_CURRENT_MSG = 43;
1199    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1200    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1201    static final int START_USER_SWITCH_MSG = 46;
1202
1203    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1204    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1205    static final int FIRST_COMPAT_MODE_MSG = 300;
1206    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1207
1208    AlertDialog mUidAlert;
1209    CompatModeDialog mCompatModeDialog;
1210    long mLastMemUsageReportTime = 0;
1211
1212    private LockToAppRequestDialog mLockToAppRequest;
1213
1214    /**
1215     * Flag whether the current user is a "monkey", i.e. whether
1216     * the UI is driven by a UI automation tool.
1217     */
1218    private boolean mUserIsMonkey;
1219
1220    /** Flag whether the device has a Recents UI */
1221    boolean mHasRecents;
1222
1223    /** The dimensions of the thumbnails in the Recents UI. */
1224    int mThumbnailWidth;
1225    int mThumbnailHeight;
1226
1227    final ServiceThread mHandlerThread;
1228    final MainHandler mHandler;
1229
1230    final class MainHandler extends Handler {
1231        public MainHandler(Looper looper) {
1232            super(looper, null, true);
1233        }
1234
1235        @Override
1236        public void handleMessage(Message msg) {
1237            switch (msg.what) {
1238            case SHOW_ERROR_MSG: {
1239                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1240                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1241                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1242                synchronized (ActivityManagerService.this) {
1243                    ProcessRecord proc = (ProcessRecord)data.get("app");
1244                    AppErrorResult res = (AppErrorResult) data.get("result");
1245                    if (proc != null && proc.crashDialog != null) {
1246                        Slog.e(TAG, "App already has crash dialog: " + proc);
1247                        if (res != null) {
1248                            res.set(0);
1249                        }
1250                        return;
1251                    }
1252                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1253                            >= Process.FIRST_APPLICATION_UID
1254                            && proc.pid != MY_PID);
1255                    for (int userId : mCurrentProfileIds) {
1256                        isBackground &= (proc.userId != userId);
1257                    }
1258                    if (isBackground && !showBackground) {
1259                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1260                        if (res != null) {
1261                            res.set(0);
1262                        }
1263                        return;
1264                    }
1265                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1266                        Dialog d = new AppErrorDialog(mContext,
1267                                ActivityManagerService.this, res, proc);
1268                        d.show();
1269                        proc.crashDialog = d;
1270                    } else {
1271                        // The device is asleep, so just pretend that the user
1272                        // saw a crash dialog and hit "force quit".
1273                        if (res != null) {
1274                            res.set(0);
1275                        }
1276                    }
1277                }
1278
1279                ensureBootCompleted();
1280            } break;
1281            case SHOW_NOT_RESPONDING_MSG: {
1282                synchronized (ActivityManagerService.this) {
1283                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1284                    ProcessRecord proc = (ProcessRecord)data.get("app");
1285                    if (proc != null && proc.anrDialog != null) {
1286                        Slog.e(TAG, "App already has anr dialog: " + proc);
1287                        return;
1288                    }
1289
1290                    Intent intent = new Intent("android.intent.action.ANR");
1291                    if (!mProcessesReady) {
1292                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1293                                | Intent.FLAG_RECEIVER_FOREGROUND);
1294                    }
1295                    broadcastIntentLocked(null, null, intent,
1296                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1297                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1298
1299                    if (mShowDialogs) {
1300                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1301                                mContext, proc, (ActivityRecord)data.get("activity"),
1302                                msg.arg1 != 0);
1303                        d.show();
1304                        proc.anrDialog = d;
1305                    } else {
1306                        // Just kill the app if there is no dialog to be shown.
1307                        killAppAtUsersRequest(proc, null);
1308                    }
1309                }
1310
1311                ensureBootCompleted();
1312            } break;
1313            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1314                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1315                synchronized (ActivityManagerService.this) {
1316                    ProcessRecord proc = (ProcessRecord) data.get("app");
1317                    if (proc == null) {
1318                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1319                        break;
1320                    }
1321                    if (proc.crashDialog != null) {
1322                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1323                        return;
1324                    }
1325                    AppErrorResult res = (AppErrorResult) data.get("result");
1326                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1327                        Dialog d = new StrictModeViolationDialog(mContext,
1328                                ActivityManagerService.this, res, proc);
1329                        d.show();
1330                        proc.crashDialog = d;
1331                    } else {
1332                        // The device is asleep, so just pretend that the user
1333                        // saw a crash dialog and hit "force quit".
1334                        res.set(0);
1335                    }
1336                }
1337                ensureBootCompleted();
1338            } break;
1339            case SHOW_FACTORY_ERROR_MSG: {
1340                Dialog d = new FactoryErrorDialog(
1341                    mContext, msg.getData().getCharSequence("msg"));
1342                d.show();
1343                ensureBootCompleted();
1344            } break;
1345            case UPDATE_CONFIGURATION_MSG: {
1346                final ContentResolver resolver = mContext.getContentResolver();
1347                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1348            } break;
1349            case GC_BACKGROUND_PROCESSES_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    performAppGcsIfAppropriateLocked();
1352                }
1353            } break;
1354            case WAIT_FOR_DEBUGGER_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    ProcessRecord app = (ProcessRecord)msg.obj;
1357                    if (msg.arg1 != 0) {
1358                        if (!app.waitedForDebugger) {
1359                            Dialog d = new AppWaitingForDebuggerDialog(
1360                                    ActivityManagerService.this,
1361                                    mContext, app);
1362                            app.waitDialog = d;
1363                            app.waitedForDebugger = true;
1364                            d.show();
1365                        }
1366                    } else {
1367                        if (app.waitDialog != null) {
1368                            app.waitDialog.dismiss();
1369                            app.waitDialog = null;
1370                        }
1371                    }
1372                }
1373            } break;
1374            case SERVICE_TIMEOUT_MSG: {
1375                if (mDidDexOpt) {
1376                    mDidDexOpt = false;
1377                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1378                    nmsg.obj = msg.obj;
1379                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1380                    return;
1381                }
1382                mServices.serviceTimeout((ProcessRecord)msg.obj);
1383            } break;
1384            case UPDATE_TIME_ZONE: {
1385                synchronized (ActivityManagerService.this) {
1386                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1387                        ProcessRecord r = mLruProcesses.get(i);
1388                        if (r.thread != null) {
1389                            try {
1390                                r.thread.updateTimeZone();
1391                            } catch (RemoteException ex) {
1392                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1393                            }
1394                        }
1395                    }
1396                }
1397            } break;
1398            case CLEAR_DNS_CACHE_MSG: {
1399                synchronized (ActivityManagerService.this) {
1400                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1401                        ProcessRecord r = mLruProcesses.get(i);
1402                        if (r.thread != null) {
1403                            try {
1404                                r.thread.clearDnsCache();
1405                            } catch (RemoteException ex) {
1406                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1407                            }
1408                        }
1409                    }
1410                }
1411            } break;
1412            case UPDATE_HTTP_PROXY_MSG: {
1413                ProxyInfo proxy = (ProxyInfo)msg.obj;
1414                String host = "";
1415                String port = "";
1416                String exclList = "";
1417                Uri pacFileUrl = Uri.EMPTY;
1418                if (proxy != null) {
1419                    host = proxy.getHost();
1420                    port = Integer.toString(proxy.getPort());
1421                    exclList = proxy.getExclusionListAsString();
1422                    pacFileUrl = proxy.getPacFileUrl();
1423                }
1424                synchronized (ActivityManagerService.this) {
1425                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1426                        ProcessRecord r = mLruProcesses.get(i);
1427                        if (r.thread != null) {
1428                            try {
1429                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1430                            } catch (RemoteException ex) {
1431                                Slog.w(TAG, "Failed to update http proxy for: " +
1432                                        r.info.processName);
1433                            }
1434                        }
1435                    }
1436                }
1437            } break;
1438            case SHOW_UID_ERROR_MSG: {
1439                String title = "System UIDs Inconsistent";
1440                String text = "UIDs on the system are inconsistent, you need to wipe your"
1441                        + " data partition or your device will be unstable.";
1442                Log.e(TAG, title + ": " + text);
1443                if (mShowDialogs) {
1444                    // XXX This is a temporary dialog, no need to localize.
1445                    AlertDialog d = new BaseErrorDialog(mContext);
1446                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1447                    d.setCancelable(false);
1448                    d.setTitle(title);
1449                    d.setMessage(text);
1450                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1451                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1452                    mUidAlert = d;
1453                    d.show();
1454                }
1455            } break;
1456            case IM_FEELING_LUCKY_MSG: {
1457                if (mUidAlert != null) {
1458                    mUidAlert.dismiss();
1459                    mUidAlert = null;
1460                }
1461            } break;
1462            case PROC_START_TIMEOUT_MSG: {
1463                if (mDidDexOpt) {
1464                    mDidDexOpt = false;
1465                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1466                    nmsg.obj = msg.obj;
1467                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1468                    return;
1469                }
1470                ProcessRecord app = (ProcessRecord)msg.obj;
1471                synchronized (ActivityManagerService.this) {
1472                    processStartTimedOutLocked(app);
1473                }
1474            } break;
1475            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1476                synchronized (ActivityManagerService.this) {
1477                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1478                }
1479            } break;
1480            case KILL_APPLICATION_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    int appid = msg.arg1;
1483                    boolean restart = (msg.arg2 == 1);
1484                    Bundle bundle = (Bundle)msg.obj;
1485                    String pkg = bundle.getString("pkg");
1486                    String reason = bundle.getString("reason");
1487                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1488                            false, UserHandle.USER_ALL, reason);
1489                }
1490            } break;
1491            case FINALIZE_PENDING_INTENT_MSG: {
1492                ((PendingIntentRecord)msg.obj).completeFinalize();
1493            } break;
1494            case POST_HEAVY_NOTIFICATION_MSG: {
1495                INotificationManager inm = NotificationManager.getService();
1496                if (inm == null) {
1497                    return;
1498                }
1499
1500                ActivityRecord root = (ActivityRecord)msg.obj;
1501                ProcessRecord process = root.app;
1502                if (process == null) {
1503                    return;
1504                }
1505
1506                try {
1507                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1508                    String text = mContext.getString(R.string.heavy_weight_notification,
1509                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1510                    Notification notification = new Notification();
1511                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1512                    notification.when = 0;
1513                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1514                    notification.tickerText = text;
1515                    notification.defaults = 0; // please be quiet
1516                    notification.sound = null;
1517                    notification.vibrate = null;
1518                    notification.color = mContext.getResources().getColor(
1519                            com.android.internal.R.color.system_notification_accent_color);
1520                    notification.setLatestEventInfo(context, text,
1521                            mContext.getText(R.string.heavy_weight_notification_detail),
1522                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1523                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1524                                    new UserHandle(root.userId)));
1525
1526                    try {
1527                        int[] outId = new int[1];
1528                        inm.enqueueNotificationWithTag("android", "android", null,
1529                                R.string.heavy_weight_notification,
1530                                notification, outId, root.userId);
1531                    } catch (RuntimeException e) {
1532                        Slog.w(ActivityManagerService.TAG,
1533                                "Error showing notification for heavy-weight app", e);
1534                    } catch (RemoteException e) {
1535                    }
1536                } catch (NameNotFoundException e) {
1537                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1538                }
1539            } break;
1540            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1541                INotificationManager inm = NotificationManager.getService();
1542                if (inm == null) {
1543                    return;
1544                }
1545                try {
1546                    inm.cancelNotificationWithTag("android", null,
1547                            R.string.heavy_weight_notification,  msg.arg1);
1548                } catch (RuntimeException e) {
1549                    Slog.w(ActivityManagerService.TAG,
1550                            "Error canceling notification for service", e);
1551                } catch (RemoteException e) {
1552                }
1553            } break;
1554            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1555                synchronized (ActivityManagerService.this) {
1556                    checkExcessivePowerUsageLocked(true);
1557                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1558                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1559                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1560                }
1561            } break;
1562            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1563                synchronized (ActivityManagerService.this) {
1564                    ActivityRecord ar = (ActivityRecord)msg.obj;
1565                    if (mCompatModeDialog != null) {
1566                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1567                                ar.info.applicationInfo.packageName)) {
1568                            return;
1569                        }
1570                        mCompatModeDialog.dismiss();
1571                        mCompatModeDialog = null;
1572                    }
1573                    if (ar != null && false) {
1574                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1575                                ar.packageName)) {
1576                            int mode = mCompatModePackages.computeCompatModeLocked(
1577                                    ar.info.applicationInfo);
1578                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1579                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1580                                mCompatModeDialog = new CompatModeDialog(
1581                                        ActivityManagerService.this, mContext,
1582                                        ar.info.applicationInfo);
1583                                mCompatModeDialog.show();
1584                            }
1585                        }
1586                    }
1587                }
1588                break;
1589            }
1590            case DISPATCH_PROCESSES_CHANGED: {
1591                dispatchProcessesChanged();
1592                break;
1593            }
1594            case DISPATCH_PROCESS_DIED: {
1595                final int pid = msg.arg1;
1596                final int uid = msg.arg2;
1597                dispatchProcessDied(pid, uid);
1598                break;
1599            }
1600            case REPORT_MEM_USAGE_MSG: {
1601                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1602                Thread thread = new Thread() {
1603                    @Override public void run() {
1604                        final SparseArray<ProcessMemInfo> infoMap
1605                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1606                        for (int i=0, N=memInfos.size(); i<N; i++) {
1607                            ProcessMemInfo mi = memInfos.get(i);
1608                            infoMap.put(mi.pid, mi);
1609                        }
1610                        updateCpuStatsNow();
1611                        synchronized (mProcessCpuTracker) {
1612                            final int N = mProcessCpuTracker.countStats();
1613                            for (int i=0; i<N; i++) {
1614                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1615                                if (st.vsize > 0) {
1616                                    long pss = Debug.getPss(st.pid, null);
1617                                    if (pss > 0) {
1618                                        if (infoMap.indexOfKey(st.pid) < 0) {
1619                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1620                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1621                                            mi.pss = pss;
1622                                            memInfos.add(mi);
1623                                        }
1624                                    }
1625                                }
1626                            }
1627                        }
1628
1629                        long totalPss = 0;
1630                        for (int i=0, N=memInfos.size(); i<N; i++) {
1631                            ProcessMemInfo mi = memInfos.get(i);
1632                            if (mi.pss == 0) {
1633                                mi.pss = Debug.getPss(mi.pid, null);
1634                            }
1635                            totalPss += mi.pss;
1636                        }
1637                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1638                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1639                                if (lhs.oomAdj != rhs.oomAdj) {
1640                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1641                                }
1642                                if (lhs.pss != rhs.pss) {
1643                                    return lhs.pss < rhs.pss ? 1 : -1;
1644                                }
1645                                return 0;
1646                            }
1647                        });
1648
1649                        StringBuilder tag = new StringBuilder(128);
1650                        StringBuilder stack = new StringBuilder(128);
1651                        tag.append("Low on memory -- ");
1652                        appendMemBucket(tag, totalPss, "total", false);
1653                        appendMemBucket(stack, totalPss, "total", true);
1654
1655                        StringBuilder logBuilder = new StringBuilder(1024);
1656                        logBuilder.append("Low on memory:\n");
1657
1658                        boolean firstLine = true;
1659                        int lastOomAdj = Integer.MIN_VALUE;
1660                        for (int i=0, N=memInfos.size(); i<N; i++) {
1661                            ProcessMemInfo mi = memInfos.get(i);
1662
1663                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1664                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1665                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1666                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1667                                if (lastOomAdj != mi.oomAdj) {
1668                                    lastOomAdj = mi.oomAdj;
1669                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1670                                        tag.append(" / ");
1671                                    }
1672                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1673                                        if (firstLine) {
1674                                            stack.append(":");
1675                                            firstLine = false;
1676                                        }
1677                                        stack.append("\n\t at ");
1678                                    } else {
1679                                        stack.append("$");
1680                                    }
1681                                } else {
1682                                    tag.append(" ");
1683                                    stack.append("$");
1684                                }
1685                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1686                                    appendMemBucket(tag, mi.pss, mi.name, false);
1687                                }
1688                                appendMemBucket(stack, mi.pss, mi.name, true);
1689                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1690                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1691                                    stack.append("(");
1692                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1693                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1694                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1695                                            stack.append(":");
1696                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1697                                        }
1698                                    }
1699                                    stack.append(")");
1700                                }
1701                            }
1702
1703                            logBuilder.append("  ");
1704                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1705                            logBuilder.append(' ');
1706                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1707                            logBuilder.append(' ');
1708                            ProcessList.appendRamKb(logBuilder, mi.pss);
1709                            logBuilder.append(" kB: ");
1710                            logBuilder.append(mi.name);
1711                            logBuilder.append(" (");
1712                            logBuilder.append(mi.pid);
1713                            logBuilder.append(") ");
1714                            logBuilder.append(mi.adjType);
1715                            logBuilder.append('\n');
1716                            if (mi.adjReason != null) {
1717                                logBuilder.append("                      ");
1718                                logBuilder.append(mi.adjReason);
1719                                logBuilder.append('\n');
1720                            }
1721                        }
1722
1723                        logBuilder.append("           ");
1724                        ProcessList.appendRamKb(logBuilder, totalPss);
1725                        logBuilder.append(" kB: TOTAL\n");
1726
1727                        long[] infos = new long[Debug.MEMINFO_COUNT];
1728                        Debug.getMemInfo(infos);
1729                        logBuilder.append("  MemInfo: ");
1730                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1731                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1732                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1733                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1734                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1735                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1736                            logBuilder.append("  ZRAM: ");
1737                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1738                            logBuilder.append(" kB RAM, ");
1739                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1740                            logBuilder.append(" kB swap total, ");
1741                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1742                            logBuilder.append(" kB swap free\n");
1743                        }
1744                        Slog.i(TAG, logBuilder.toString());
1745
1746                        StringBuilder dropBuilder = new StringBuilder(1024);
1747                        /*
1748                        StringWriter oomSw = new StringWriter();
1749                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1750                        StringWriter catSw = new StringWriter();
1751                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1752                        String[] emptyArgs = new String[] { };
1753                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1754                        oomPw.flush();
1755                        String oomString = oomSw.toString();
1756                        */
1757                        dropBuilder.append(stack);
1758                        dropBuilder.append('\n');
1759                        dropBuilder.append('\n');
1760                        dropBuilder.append(logBuilder);
1761                        dropBuilder.append('\n');
1762                        /*
1763                        dropBuilder.append(oomString);
1764                        dropBuilder.append('\n');
1765                        */
1766                        StringWriter catSw = new StringWriter();
1767                        synchronized (ActivityManagerService.this) {
1768                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1769                            String[] emptyArgs = new String[] { };
1770                            catPw.println();
1771                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1772                            catPw.println();
1773                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1774                                    false, false, null);
1775                            catPw.println();
1776                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1777                            catPw.flush();
1778                        }
1779                        dropBuilder.append(catSw.toString());
1780                        addErrorToDropBox("lowmem", null, "system_server", null,
1781                                null, tag.toString(), dropBuilder.toString(), null, null);
1782                        //Slog.i(TAG, "Sent to dropbox:");
1783                        //Slog.i(TAG, dropBuilder.toString());
1784                        synchronized (ActivityManagerService.this) {
1785                            long now = SystemClock.uptimeMillis();
1786                            if (mLastMemUsageReportTime < now) {
1787                                mLastMemUsageReportTime = now;
1788                            }
1789                        }
1790                    }
1791                };
1792                thread.start();
1793                break;
1794            }
1795            case START_USER_SWITCH_MSG: {
1796                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1797                break;
1798            }
1799            case REPORT_USER_SWITCH_MSG: {
1800                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1801                break;
1802            }
1803            case CONTINUE_USER_SWITCH_MSG: {
1804                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1805                break;
1806            }
1807            case USER_SWITCH_TIMEOUT_MSG: {
1808                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1809                break;
1810            }
1811            case IMMERSIVE_MODE_LOCK_MSG: {
1812                final boolean nextState = (msg.arg1 != 0);
1813                if (mUpdateLock.isHeld() != nextState) {
1814                    if (DEBUG_IMMERSIVE) {
1815                        final ActivityRecord r = (ActivityRecord) msg.obj;
1816                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1817                    }
1818                    if (nextState) {
1819                        mUpdateLock.acquire();
1820                    } else {
1821                        mUpdateLock.release();
1822                    }
1823                }
1824                break;
1825            }
1826            case PERSIST_URI_GRANTS_MSG: {
1827                writeGrantedUriPermissions();
1828                break;
1829            }
1830            case REQUEST_ALL_PSS_MSG: {
1831                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1832                break;
1833            }
1834            case START_PROFILES_MSG: {
1835                synchronized (ActivityManagerService.this) {
1836                    startProfilesLocked();
1837                }
1838                break;
1839            }
1840            case UPDATE_TIME: {
1841                synchronized (ActivityManagerService.this) {
1842                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1843                        ProcessRecord r = mLruProcesses.get(i);
1844                        if (r.thread != null) {
1845                            try {
1846                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1847                            } catch (RemoteException ex) {
1848                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1849                            }
1850                        }
1851                    }
1852                }
1853                break;
1854            }
1855            case SYSTEM_USER_START_MSG: {
1856                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1857                        Integer.toString(msg.arg1), msg.arg1);
1858                mSystemServiceManager.startUser(msg.arg1);
1859                break;
1860            }
1861            case SYSTEM_USER_CURRENT_MSG: {
1862                mBatteryStatsService.noteEvent(
1863                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1864                        Integer.toString(msg.arg2), msg.arg2);
1865                mBatteryStatsService.noteEvent(
1866                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1867                        Integer.toString(msg.arg1), msg.arg1);
1868                mSystemServiceManager.switchUser(msg.arg1);
1869                mLockToAppRequest.clearPrompt();
1870                break;
1871            }
1872            case ENTER_ANIMATION_COMPLETE_MSG: {
1873                synchronized (ActivityManagerService.this) {
1874                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1875                    if (r != null && r.app != null && r.app.thread != null) {
1876                        try {
1877                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1878                        } catch (RemoteException e) {
1879                        }
1880                    }
1881                }
1882                break;
1883            }
1884            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1885                enableScreenAfterBoot();
1886                break;
1887            }
1888            }
1889        }
1890    };
1891
1892    static final int COLLECT_PSS_BG_MSG = 1;
1893
1894    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1895        @Override
1896        public void handleMessage(Message msg) {
1897            switch (msg.what) {
1898            case COLLECT_PSS_BG_MSG: {
1899                long start = SystemClock.uptimeMillis();
1900                MemInfoReader memInfo = null;
1901                synchronized (ActivityManagerService.this) {
1902                    if (mFullPssPending) {
1903                        mFullPssPending = false;
1904                        memInfo = new MemInfoReader();
1905                    }
1906                }
1907                if (memInfo != null) {
1908                    updateCpuStatsNow();
1909                    long nativeTotalPss = 0;
1910                    synchronized (mProcessCpuTracker) {
1911                        final int N = mProcessCpuTracker.countStats();
1912                        for (int j=0; j<N; j++) {
1913                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1914                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1915                                // This is definitely an application process; skip it.
1916                                continue;
1917                            }
1918                            synchronized (mPidsSelfLocked) {
1919                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1920                                    // This is one of our own processes; skip it.
1921                                    continue;
1922                                }
1923                            }
1924                            nativeTotalPss += Debug.getPss(st.pid, null);
1925                        }
1926                    }
1927                    memInfo.readMemInfo();
1928                    synchronized (ActivityManagerService.this) {
1929                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1930                                + (SystemClock.uptimeMillis()-start) + "ms");
1931                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1932                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1933                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1934                                        +memInfo.getSlabSizeKb(),
1935                                nativeTotalPss);
1936                    }
1937                }
1938
1939                int i=0, num=0;
1940                long[] tmp = new long[1];
1941                do {
1942                    ProcessRecord proc;
1943                    int procState;
1944                    int pid;
1945                    synchronized (ActivityManagerService.this) {
1946                        if (i >= mPendingPssProcesses.size()) {
1947                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1948                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1949                            mPendingPssProcesses.clear();
1950                            return;
1951                        }
1952                        proc = mPendingPssProcesses.get(i);
1953                        procState = proc.pssProcState;
1954                        if (proc.thread != null && procState == proc.setProcState) {
1955                            pid = proc.pid;
1956                        } else {
1957                            proc = null;
1958                            pid = 0;
1959                        }
1960                        i++;
1961                    }
1962                    if (proc != null) {
1963                        long pss = Debug.getPss(pid, tmp);
1964                        synchronized (ActivityManagerService.this) {
1965                            if (proc.thread != null && proc.setProcState == procState
1966                                    && proc.pid == pid) {
1967                                num++;
1968                                proc.lastPssTime = SystemClock.uptimeMillis();
1969                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1970                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1971                                        + ": " + pss + " lastPss=" + proc.lastPss
1972                                        + " state=" + ProcessList.makeProcStateString(procState));
1973                                if (proc.initialIdlePss == 0) {
1974                                    proc.initialIdlePss = pss;
1975                                }
1976                                proc.lastPss = pss;
1977                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1978                                    proc.lastCachedPss = pss;
1979                                }
1980                            }
1981                        }
1982                    }
1983                } while (true);
1984            }
1985            }
1986        }
1987    };
1988
1989    /**
1990     * Monitor for package changes and update our internal state.
1991     */
1992    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1993        @Override
1994        public void onPackageRemoved(String packageName, int uid) {
1995            // Remove all tasks with activities in the specified package from the list of recent tasks
1996            synchronized (ActivityManagerService.this) {
1997                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1998                    TaskRecord tr = mRecentTasks.get(i);
1999                    ComponentName cn = tr.intent.getComponent();
2000                    if (cn != null && cn.getPackageName().equals(packageName)) {
2001                        // If the package name matches, remove the task and kill the process
2002                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2003                    }
2004                }
2005            }
2006        }
2007
2008        @Override
2009        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2010            onPackageModified(packageName);
2011            return true;
2012        }
2013
2014        @Override
2015        public void onPackageModified(String packageName) {
2016            final PackageManager pm = mContext.getPackageManager();
2017            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2018                    new ArrayList<Pair<Intent, Integer>>();
2019            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2020            // Copy the list of recent tasks so that we don't hold onto the lock on
2021            // ActivityManagerService for long periods while checking if components exist.
2022            synchronized (ActivityManagerService.this) {
2023                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2024                    TaskRecord tr = mRecentTasks.get(i);
2025                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2026                }
2027            }
2028            // Check the recent tasks and filter out all tasks with components that no longer exist.
2029            Intent tmpI = new Intent();
2030            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2031                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2032                ComponentName cn = p.first.getComponent();
2033                if (cn != null && cn.getPackageName().equals(packageName)) {
2034                    try {
2035                        // Add the task to the list to remove if the component no longer exists
2036                        tmpI.setComponent(cn);
2037                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2038                            tasksToRemove.add(p.second);
2039                        }
2040                    } catch (Exception e) {}
2041                }
2042            }
2043            // Prune all the tasks with removed components from the list of recent tasks
2044            synchronized (ActivityManagerService.this) {
2045                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2046                    // Remove the task but don't kill the process (since other components in that
2047                    // package may still be running and in the background)
2048                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2049                }
2050            }
2051        }
2052
2053        @Override
2054        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2055            // Force stop the specified packages
2056            if (packages != null) {
2057                for (String pkg : packages) {
2058                    synchronized (ActivityManagerService.this) {
2059                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2060                                "finished booting")) {
2061                            return true;
2062                        }
2063                    }
2064                }
2065            }
2066            return false;
2067        }
2068    };
2069
2070    public void setSystemProcess() {
2071        try {
2072            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2073            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2074            ServiceManager.addService("meminfo", new MemBinder(this));
2075            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2076            ServiceManager.addService("dbinfo", new DbBinder(this));
2077            if (MONITOR_CPU_USAGE) {
2078                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2079            }
2080            ServiceManager.addService("permission", new PermissionController(this));
2081
2082            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2083                    "android", STOCK_PM_FLAGS);
2084            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2085
2086            synchronized (this) {
2087                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2088                app.persistent = true;
2089                app.pid = MY_PID;
2090                app.maxAdj = ProcessList.SYSTEM_ADJ;
2091                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2092                mProcessNames.put(app.processName, app.uid, app);
2093                synchronized (mPidsSelfLocked) {
2094                    mPidsSelfLocked.put(app.pid, app);
2095                }
2096                updateLruProcessLocked(app, false, null);
2097                updateOomAdjLocked();
2098            }
2099        } catch (PackageManager.NameNotFoundException e) {
2100            throw new RuntimeException(
2101                    "Unable to find android system package", e);
2102        }
2103    }
2104
2105    public void setWindowManager(WindowManagerService wm) {
2106        mWindowManager = wm;
2107        mStackSupervisor.setWindowManager(wm);
2108    }
2109
2110    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2111        mUsageStatsService = usageStatsManager;
2112    }
2113
2114    public void startObservingNativeCrashes() {
2115        final NativeCrashListener ncl = new NativeCrashListener(this);
2116        ncl.start();
2117    }
2118
2119    public IAppOpsService getAppOpsService() {
2120        return mAppOpsService;
2121    }
2122
2123    static class MemBinder extends Binder {
2124        ActivityManagerService mActivityManagerService;
2125        MemBinder(ActivityManagerService activityManagerService) {
2126            mActivityManagerService = activityManagerService;
2127        }
2128
2129        @Override
2130        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2131            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2132                    != PackageManager.PERMISSION_GRANTED) {
2133                pw.println("Permission Denial: can't dump meminfo from from pid="
2134                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2135                        + " without permission " + android.Manifest.permission.DUMP);
2136                return;
2137            }
2138
2139            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2140        }
2141    }
2142
2143    static class GraphicsBinder extends Binder {
2144        ActivityManagerService mActivityManagerService;
2145        GraphicsBinder(ActivityManagerService activityManagerService) {
2146            mActivityManagerService = activityManagerService;
2147        }
2148
2149        @Override
2150        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2151            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2152                    != PackageManager.PERMISSION_GRANTED) {
2153                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2154                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2155                        + " without permission " + android.Manifest.permission.DUMP);
2156                return;
2157            }
2158
2159            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2160        }
2161    }
2162
2163    static class DbBinder extends Binder {
2164        ActivityManagerService mActivityManagerService;
2165        DbBinder(ActivityManagerService activityManagerService) {
2166            mActivityManagerService = activityManagerService;
2167        }
2168
2169        @Override
2170        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2171            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2172                    != PackageManager.PERMISSION_GRANTED) {
2173                pw.println("Permission Denial: can't dump dbinfo from from pid="
2174                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2175                        + " without permission " + android.Manifest.permission.DUMP);
2176                return;
2177            }
2178
2179            mActivityManagerService.dumpDbInfo(fd, pw, args);
2180        }
2181    }
2182
2183    static class CpuBinder extends Binder {
2184        ActivityManagerService mActivityManagerService;
2185        CpuBinder(ActivityManagerService activityManagerService) {
2186            mActivityManagerService = activityManagerService;
2187        }
2188
2189        @Override
2190        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2191            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2192                    != PackageManager.PERMISSION_GRANTED) {
2193                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2194                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2195                        + " without permission " + android.Manifest.permission.DUMP);
2196                return;
2197            }
2198
2199            synchronized (mActivityManagerService.mProcessCpuTracker) {
2200                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2201                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2202                        SystemClock.uptimeMillis()));
2203            }
2204        }
2205    }
2206
2207    public static final class Lifecycle extends SystemService {
2208        private final ActivityManagerService mService;
2209
2210        public Lifecycle(Context context) {
2211            super(context);
2212            mService = new ActivityManagerService(context);
2213        }
2214
2215        @Override
2216        public void onStart() {
2217            mService.start();
2218        }
2219
2220        public ActivityManagerService getService() {
2221            return mService;
2222        }
2223    }
2224
2225    // Note: This method is invoked on the main thread but may need to attach various
2226    // handlers to other threads.  So take care to be explicit about the looper.
2227    public ActivityManagerService(Context systemContext) {
2228        mContext = systemContext;
2229        mFactoryTest = FactoryTest.getMode();
2230        mSystemThread = ActivityThread.currentActivityThread();
2231
2232        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2233
2234        mHandlerThread = new ServiceThread(TAG,
2235                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2236        mHandlerThread.start();
2237        mHandler = new MainHandler(mHandlerThread.getLooper());
2238
2239        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2240                "foreground", BROADCAST_FG_TIMEOUT, false);
2241        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2242                "background", BROADCAST_BG_TIMEOUT, true);
2243        mBroadcastQueues[0] = mFgBroadcastQueue;
2244        mBroadcastQueues[1] = mBgBroadcastQueue;
2245
2246        mServices = new ActiveServices(this);
2247        mProviderMap = new ProviderMap(this);
2248
2249        // TODO: Move creation of battery stats service outside of activity manager service.
2250        File dataDir = Environment.getDataDirectory();
2251        File systemDir = new File(dataDir, "system");
2252        systemDir.mkdirs();
2253        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2254        mBatteryStatsService.getActiveStatistics().readLocked();
2255        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2256        mOnBattery = DEBUG_POWER ? true
2257                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2258        mBatteryStatsService.getActiveStatistics().setCallback(this);
2259
2260        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2261
2262        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2263
2264        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2265
2266        // User 0 is the first and only user that runs at boot.
2267        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2268        mUserLru.add(Integer.valueOf(0));
2269        updateStartedUserArrayLocked();
2270
2271        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2272            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2273
2274        mConfiguration.setToDefaults();
2275        mConfiguration.setLocale(Locale.getDefault());
2276
2277        mConfigurationSeq = mConfiguration.seq = 1;
2278        mProcessCpuTracker.init();
2279
2280        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2281        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2282        mStackSupervisor = new ActivityStackSupervisor(this);
2283        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2284
2285        mProcessCpuThread = new Thread("CpuTracker") {
2286            @Override
2287            public void run() {
2288                while (true) {
2289                    try {
2290                        try {
2291                            synchronized(this) {
2292                                final long now = SystemClock.uptimeMillis();
2293                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2294                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2295                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2296                                //        + ", write delay=" + nextWriteDelay);
2297                                if (nextWriteDelay < nextCpuDelay) {
2298                                    nextCpuDelay = nextWriteDelay;
2299                                }
2300                                if (nextCpuDelay > 0) {
2301                                    mProcessCpuMutexFree.set(true);
2302                                    this.wait(nextCpuDelay);
2303                                }
2304                            }
2305                        } catch (InterruptedException e) {
2306                        }
2307                        updateCpuStatsNow();
2308                    } catch (Exception e) {
2309                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2310                    }
2311                }
2312            }
2313        };
2314
2315        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2316
2317        Watchdog.getInstance().addMonitor(this);
2318        Watchdog.getInstance().addThread(mHandler);
2319    }
2320
2321    public void setSystemServiceManager(SystemServiceManager mgr) {
2322        mSystemServiceManager = mgr;
2323    }
2324
2325    private void start() {
2326        Process.removeAllProcessGroups();
2327        mProcessCpuThread.start();
2328
2329        mBatteryStatsService.publish(mContext);
2330        mAppOpsService.publish(mContext);
2331        Slog.d("AppOps", "AppOpsService published");
2332        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2333    }
2334
2335    public void initPowerManagement() {
2336        mStackSupervisor.initPowerManagement();
2337        mBatteryStatsService.initPowerManagement();
2338    }
2339
2340    @Override
2341    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2342            throws RemoteException {
2343        if (code == SYSPROPS_TRANSACTION) {
2344            // We need to tell all apps about the system property change.
2345            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2346            synchronized(this) {
2347                final int NP = mProcessNames.getMap().size();
2348                for (int ip=0; ip<NP; ip++) {
2349                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2350                    final int NA = apps.size();
2351                    for (int ia=0; ia<NA; ia++) {
2352                        ProcessRecord app = apps.valueAt(ia);
2353                        if (app.thread != null) {
2354                            procs.add(app.thread.asBinder());
2355                        }
2356                    }
2357                }
2358            }
2359
2360            int N = procs.size();
2361            for (int i=0; i<N; i++) {
2362                Parcel data2 = Parcel.obtain();
2363                try {
2364                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2365                } catch (RemoteException e) {
2366                }
2367                data2.recycle();
2368            }
2369        }
2370        try {
2371            return super.onTransact(code, data, reply, flags);
2372        } catch (RuntimeException e) {
2373            // The activity manager only throws security exceptions, so let's
2374            // log all others.
2375            if (!(e instanceof SecurityException)) {
2376                Slog.wtf(TAG, "Activity Manager Crash", e);
2377            }
2378            throw e;
2379        }
2380    }
2381
2382    void updateCpuStats() {
2383        final long now = SystemClock.uptimeMillis();
2384        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2385            return;
2386        }
2387        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2388            synchronized (mProcessCpuThread) {
2389                mProcessCpuThread.notify();
2390            }
2391        }
2392    }
2393
2394    void updateCpuStatsNow() {
2395        synchronized (mProcessCpuTracker) {
2396            mProcessCpuMutexFree.set(false);
2397            final long now = SystemClock.uptimeMillis();
2398            boolean haveNewCpuStats = false;
2399
2400            if (MONITOR_CPU_USAGE &&
2401                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2402                mLastCpuTime.set(now);
2403                haveNewCpuStats = true;
2404                mProcessCpuTracker.update();
2405                //Slog.i(TAG, mProcessCpu.printCurrentState());
2406                //Slog.i(TAG, "Total CPU usage: "
2407                //        + mProcessCpu.getTotalCpuPercent() + "%");
2408
2409                // Slog the cpu usage if the property is set.
2410                if ("true".equals(SystemProperties.get("events.cpu"))) {
2411                    int user = mProcessCpuTracker.getLastUserTime();
2412                    int system = mProcessCpuTracker.getLastSystemTime();
2413                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2414                    int irq = mProcessCpuTracker.getLastIrqTime();
2415                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2416                    int idle = mProcessCpuTracker.getLastIdleTime();
2417
2418                    int total = user + system + iowait + irq + softIrq + idle;
2419                    if (total == 0) total = 1;
2420
2421                    EventLog.writeEvent(EventLogTags.CPU,
2422                            ((user+system+iowait+irq+softIrq) * 100) / total,
2423                            (user * 100) / total,
2424                            (system * 100) / total,
2425                            (iowait * 100) / total,
2426                            (irq * 100) / total,
2427                            (softIrq * 100) / total);
2428                }
2429            }
2430
2431            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2432            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2433            synchronized(bstats) {
2434                synchronized(mPidsSelfLocked) {
2435                    if (haveNewCpuStats) {
2436                        if (mOnBattery) {
2437                            int perc = bstats.startAddingCpuLocked();
2438                            int totalUTime = 0;
2439                            int totalSTime = 0;
2440                            final int N = mProcessCpuTracker.countStats();
2441                            for (int i=0; i<N; i++) {
2442                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2443                                if (!st.working) {
2444                                    continue;
2445                                }
2446                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2447                                int otherUTime = (st.rel_utime*perc)/100;
2448                                int otherSTime = (st.rel_stime*perc)/100;
2449                                totalUTime += otherUTime;
2450                                totalSTime += otherSTime;
2451                                if (pr != null) {
2452                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2453                                    if (ps == null || !ps.isActive()) {
2454                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2455                                                pr.info.uid, pr.processName);
2456                                    }
2457                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2458                                            st.rel_stime-otherSTime);
2459                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2460                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2461                                } else {
2462                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2463                                    if (ps == null || !ps.isActive()) {
2464                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2465                                                bstats.mapUid(st.uid), st.name);
2466                                    }
2467                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2468                                            st.rel_stime-otherSTime);
2469                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2470                                }
2471                            }
2472                            bstats.finishAddingCpuLocked(perc, totalUTime,
2473                                    totalSTime, cpuSpeedTimes);
2474                        }
2475                    }
2476                }
2477
2478                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2479                    mLastWriteTime = now;
2480                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2481                }
2482            }
2483        }
2484    }
2485
2486    @Override
2487    public void batteryNeedsCpuUpdate() {
2488        updateCpuStatsNow();
2489    }
2490
2491    @Override
2492    public void batteryPowerChanged(boolean onBattery) {
2493        // When plugging in, update the CPU stats first before changing
2494        // the plug state.
2495        updateCpuStatsNow();
2496        synchronized (this) {
2497            synchronized(mPidsSelfLocked) {
2498                mOnBattery = DEBUG_POWER ? true : onBattery;
2499            }
2500        }
2501    }
2502
2503    /**
2504     * Initialize the application bind args. These are passed to each
2505     * process when the bindApplication() IPC is sent to the process. They're
2506     * lazily setup to make sure the services are running when they're asked for.
2507     */
2508    private HashMap<String, IBinder> getCommonServicesLocked() {
2509        if (mAppBindArgs == null) {
2510            mAppBindArgs = new HashMap<String, IBinder>();
2511
2512            // Setup the application init args
2513            mAppBindArgs.put("package", ServiceManager.getService("package"));
2514            mAppBindArgs.put("window", ServiceManager.getService("window"));
2515            mAppBindArgs.put(Context.ALARM_SERVICE,
2516                    ServiceManager.getService(Context.ALARM_SERVICE));
2517        }
2518        return mAppBindArgs;
2519    }
2520
2521    final void setFocusedActivityLocked(ActivityRecord r) {
2522        if (mFocusedActivity != r) {
2523            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2524            mFocusedActivity = r;
2525            if (r.task != null && r.task.voiceInteractor != null) {
2526                startRunningVoiceLocked();
2527            } else {
2528                finishRunningVoiceLocked();
2529            }
2530            mStackSupervisor.setFocusedStack(r);
2531            if (r != null) {
2532                mWindowManager.setFocusedApp(r.appToken, true);
2533            }
2534            applyUpdateLockStateLocked(r);
2535        }
2536    }
2537
2538    final void clearFocusedActivity(ActivityRecord r) {
2539        if (mFocusedActivity == r) {
2540            mFocusedActivity = null;
2541        }
2542    }
2543
2544    @Override
2545    public void setFocusedStack(int stackId) {
2546        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2547        synchronized (ActivityManagerService.this) {
2548            ActivityStack stack = mStackSupervisor.getStack(stackId);
2549            if (stack != null) {
2550                ActivityRecord r = stack.topRunningActivityLocked(null);
2551                if (r != null) {
2552                    setFocusedActivityLocked(r);
2553                }
2554            }
2555        }
2556    }
2557
2558    @Override
2559    public void notifyActivityDrawn(IBinder token) {
2560        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2561        synchronized (this) {
2562            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2563            if (r != null) {
2564                r.task.stack.notifyActivityDrawnLocked(r);
2565            }
2566        }
2567    }
2568
2569    final void applyUpdateLockStateLocked(ActivityRecord r) {
2570        // Modifications to the UpdateLock state are done on our handler, outside
2571        // the activity manager's locks.  The new state is determined based on the
2572        // state *now* of the relevant activity record.  The object is passed to
2573        // the handler solely for logging detail, not to be consulted/modified.
2574        final boolean nextState = r != null && r.immersive;
2575        mHandler.sendMessage(
2576                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2577    }
2578
2579    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2580        Message msg = Message.obtain();
2581        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2582        msg.obj = r.task.askedCompatMode ? null : r;
2583        mHandler.sendMessage(msg);
2584    }
2585
2586    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2587            String what, Object obj, ProcessRecord srcApp) {
2588        app.lastActivityTime = now;
2589
2590        if (app.activities.size() > 0) {
2591            // Don't want to touch dependent processes that are hosting activities.
2592            return index;
2593        }
2594
2595        int lrui = mLruProcesses.lastIndexOf(app);
2596        if (lrui < 0) {
2597            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2598                    + what + " " + obj + " from " + srcApp);
2599            return index;
2600        }
2601
2602        if (lrui >= index) {
2603            // Don't want to cause this to move dependent processes *back* in the
2604            // list as if they were less frequently used.
2605            return index;
2606        }
2607
2608        if (lrui >= mLruProcessActivityStart) {
2609            // Don't want to touch dependent processes that are hosting activities.
2610            return index;
2611        }
2612
2613        mLruProcesses.remove(lrui);
2614        if (index > 0) {
2615            index--;
2616        }
2617        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2618                + " in LRU list: " + app);
2619        mLruProcesses.add(index, app);
2620        return index;
2621    }
2622
2623    final void removeLruProcessLocked(ProcessRecord app) {
2624        int lrui = mLruProcesses.lastIndexOf(app);
2625        if (lrui >= 0) {
2626            if (lrui <= mLruProcessActivityStart) {
2627                mLruProcessActivityStart--;
2628            }
2629            if (lrui <= mLruProcessServiceStart) {
2630                mLruProcessServiceStart--;
2631            }
2632            mLruProcesses.remove(lrui);
2633        }
2634    }
2635
2636    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2637            ProcessRecord client) {
2638        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2639                || app.treatLikeActivity;
2640        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2641        if (!activityChange && hasActivity) {
2642            // The process has activities, so we are only allowing activity-based adjustments
2643            // to move it.  It should be kept in the front of the list with other
2644            // processes that have activities, and we don't want those to change their
2645            // order except due to activity operations.
2646            return;
2647        }
2648
2649        mLruSeq++;
2650        final long now = SystemClock.uptimeMillis();
2651        app.lastActivityTime = now;
2652
2653        // First a quick reject: if the app is already at the position we will
2654        // put it, then there is nothing to do.
2655        if (hasActivity) {
2656            final int N = mLruProcesses.size();
2657            if (N > 0 && mLruProcesses.get(N-1) == app) {
2658                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2659                return;
2660            }
2661        } else {
2662            if (mLruProcessServiceStart > 0
2663                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2664                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2665                return;
2666            }
2667        }
2668
2669        int lrui = mLruProcesses.lastIndexOf(app);
2670
2671        if (app.persistent && lrui >= 0) {
2672            // We don't care about the position of persistent processes, as long as
2673            // they are in the list.
2674            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2675            return;
2676        }
2677
2678        /* In progress: compute new position first, so we can avoid doing work
2679           if the process is not actually going to move.  Not yet working.
2680        int addIndex;
2681        int nextIndex;
2682        boolean inActivity = false, inService = false;
2683        if (hasActivity) {
2684            // Process has activities, put it at the very tipsy-top.
2685            addIndex = mLruProcesses.size();
2686            nextIndex = mLruProcessServiceStart;
2687            inActivity = true;
2688        } else if (hasService) {
2689            // Process has services, put it at the top of the service list.
2690            addIndex = mLruProcessActivityStart;
2691            nextIndex = mLruProcessServiceStart;
2692            inActivity = true;
2693            inService = true;
2694        } else  {
2695            // Process not otherwise of interest, it goes to the top of the non-service area.
2696            addIndex = mLruProcessServiceStart;
2697            if (client != null) {
2698                int clientIndex = mLruProcesses.lastIndexOf(client);
2699                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2700                        + app);
2701                if (clientIndex >= 0 && addIndex > clientIndex) {
2702                    addIndex = clientIndex;
2703                }
2704            }
2705            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2706        }
2707
2708        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2709                + mLruProcessActivityStart + "): " + app);
2710        */
2711
2712        if (lrui >= 0) {
2713            if (lrui < mLruProcessActivityStart) {
2714                mLruProcessActivityStart--;
2715            }
2716            if (lrui < mLruProcessServiceStart) {
2717                mLruProcessServiceStart--;
2718            }
2719            /*
2720            if (addIndex > lrui) {
2721                addIndex--;
2722            }
2723            if (nextIndex > lrui) {
2724                nextIndex--;
2725            }
2726            */
2727            mLruProcesses.remove(lrui);
2728        }
2729
2730        /*
2731        mLruProcesses.add(addIndex, app);
2732        if (inActivity) {
2733            mLruProcessActivityStart++;
2734        }
2735        if (inService) {
2736            mLruProcessActivityStart++;
2737        }
2738        */
2739
2740        int nextIndex;
2741        if (hasActivity) {
2742            final int N = mLruProcesses.size();
2743            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2744                // Process doesn't have activities, but has clients with
2745                // activities...  move it up, but one below the top (the top
2746                // should always have a real activity).
2747                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2748                mLruProcesses.add(N-1, app);
2749                // To keep it from spamming the LRU list (by making a bunch of clients),
2750                // we will push down any other entries owned by the app.
2751                final int uid = app.info.uid;
2752                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2753                    ProcessRecord subProc = mLruProcesses.get(i);
2754                    if (subProc.info.uid == uid) {
2755                        // We want to push this one down the list.  If the process after
2756                        // it is for the same uid, however, don't do so, because we don't
2757                        // want them internally to be re-ordered.
2758                        if (mLruProcesses.get(i-1).info.uid != uid) {
2759                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2760                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2761                            ProcessRecord tmp = mLruProcesses.get(i);
2762                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2763                            mLruProcesses.set(i-1, tmp);
2764                            i--;
2765                        }
2766                    } else {
2767                        // A gap, we can stop here.
2768                        break;
2769                    }
2770                }
2771            } else {
2772                // Process has activities, put it at the very tipsy-top.
2773                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2774                mLruProcesses.add(app);
2775            }
2776            nextIndex = mLruProcessServiceStart;
2777        } else if (hasService) {
2778            // Process has services, put it at the top of the service list.
2779            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2780            mLruProcesses.add(mLruProcessActivityStart, app);
2781            nextIndex = mLruProcessServiceStart;
2782            mLruProcessActivityStart++;
2783        } else  {
2784            // Process not otherwise of interest, it goes to the top of the non-service area.
2785            int index = mLruProcessServiceStart;
2786            if (client != null) {
2787                // If there is a client, don't allow the process to be moved up higher
2788                // in the list than that client.
2789                int clientIndex = mLruProcesses.lastIndexOf(client);
2790                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2791                        + " when updating " + app);
2792                if (clientIndex <= lrui) {
2793                    // Don't allow the client index restriction to push it down farther in the
2794                    // list than it already is.
2795                    clientIndex = lrui;
2796                }
2797                if (clientIndex >= 0 && index > clientIndex) {
2798                    index = clientIndex;
2799                }
2800            }
2801            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2802            mLruProcesses.add(index, app);
2803            nextIndex = index-1;
2804            mLruProcessActivityStart++;
2805            mLruProcessServiceStart++;
2806        }
2807
2808        // If the app is currently using a content provider or service,
2809        // bump those processes as well.
2810        for (int j=app.connections.size()-1; j>=0; j--) {
2811            ConnectionRecord cr = app.connections.valueAt(j);
2812            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2813                    && cr.binding.service.app != null
2814                    && cr.binding.service.app.lruSeq != mLruSeq
2815                    && !cr.binding.service.app.persistent) {
2816                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2817                        "service connection", cr, app);
2818            }
2819        }
2820        for (int j=app.conProviders.size()-1; j>=0; j--) {
2821            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2822            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2823                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2824                        "provider reference", cpr, app);
2825            }
2826        }
2827    }
2828
2829    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2830        if (uid == Process.SYSTEM_UID) {
2831            // The system gets to run in any process.  If there are multiple
2832            // processes with the same uid, just pick the first (this
2833            // should never happen).
2834            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2835            if (procs == null) return null;
2836            final int N = procs.size();
2837            for (int i = 0; i < N; i++) {
2838                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2839            }
2840        }
2841        ProcessRecord proc = mProcessNames.get(processName, uid);
2842        if (false && proc != null && !keepIfLarge
2843                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2844                && proc.lastCachedPss >= 4000) {
2845            // Turn this condition on to cause killing to happen regularly, for testing.
2846            if (proc.baseProcessTracker != null) {
2847                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2848            }
2849            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2850        } else if (proc != null && !keepIfLarge
2851                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2852                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2853            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2854            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2855                if (proc.baseProcessTracker != null) {
2856                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2857                }
2858                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2859            }
2860        }
2861        return proc;
2862    }
2863
2864    void ensurePackageDexOpt(String packageName) {
2865        IPackageManager pm = AppGlobals.getPackageManager();
2866        try {
2867            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2868                mDidDexOpt = true;
2869            }
2870        } catch (RemoteException e) {
2871        }
2872    }
2873
2874    boolean isNextTransitionForward() {
2875        int transit = mWindowManager.getPendingAppTransition();
2876        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2877                || transit == AppTransition.TRANSIT_TASK_OPEN
2878                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2879    }
2880
2881    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2882            String processName, String abiOverride, int uid, Runnable crashHandler) {
2883        synchronized(this) {
2884            ApplicationInfo info = new ApplicationInfo();
2885            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2886            // For isolated processes, the former contains the parent's uid and the latter the
2887            // actual uid of the isolated process.
2888            // In the special case introduced by this method (which is, starting an isolated
2889            // process directly from the SystemServer without an actual parent app process) the
2890            // closest thing to a parent's uid is SYSTEM_UID.
2891            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2892            // the |isolated| logic in the ProcessRecord constructor.
2893            info.uid = Process.SYSTEM_UID;
2894            info.processName = processName;
2895            info.className = entryPoint;
2896            info.packageName = "android";
2897            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2898                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2899                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2900                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2901                    crashHandler);
2902            return proc != null ? proc.pid : 0;
2903        }
2904    }
2905
2906    final ProcessRecord startProcessLocked(String processName,
2907            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2908            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2909            boolean isolated, boolean keepIfLarge) {
2910        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2911                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2912                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2913                null /* crashHandler */);
2914    }
2915
2916    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2917            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2918            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2919            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2920        long startTime = SystemClock.elapsedRealtime();
2921        ProcessRecord app;
2922        if (!isolated) {
2923            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2924            checkTime(startTime, "startProcess: after getProcessRecord");
2925        } else {
2926            // If this is an isolated process, it can't re-use an existing process.
2927            app = null;
2928        }
2929        // We don't have to do anything more if:
2930        // (1) There is an existing application record; and
2931        // (2) The caller doesn't think it is dead, OR there is no thread
2932        //     object attached to it so we know it couldn't have crashed; and
2933        // (3) There is a pid assigned to it, so it is either starting or
2934        //     already running.
2935        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2936                + " app=" + app + " knownToBeDead=" + knownToBeDead
2937                + " thread=" + (app != null ? app.thread : null)
2938                + " pid=" + (app != null ? app.pid : -1));
2939        if (app != null && app.pid > 0) {
2940            if (!knownToBeDead || app.thread == null) {
2941                // We already have the app running, or are waiting for it to
2942                // come up (we have a pid but not yet its thread), so keep it.
2943                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2944                // If this is a new package in the process, add the package to the list
2945                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2946                checkTime(startTime, "startProcess: done, added package to proc");
2947                return app;
2948            }
2949
2950            // An application record is attached to a previous process,
2951            // clean it up now.
2952            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2953            checkTime(startTime, "startProcess: bad proc running, killing");
2954            Process.killProcessGroup(app.info.uid, app.pid);
2955            handleAppDiedLocked(app, true, true);
2956            checkTime(startTime, "startProcess: done killing old proc");
2957        }
2958
2959        String hostingNameStr = hostingName != null
2960                ? hostingName.flattenToShortString() : null;
2961
2962        if (!isolated) {
2963            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2964                // If we are in the background, then check to see if this process
2965                // is bad.  If so, we will just silently fail.
2966                if (mBadProcesses.get(info.processName, info.uid) != null) {
2967                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2968                            + "/" + info.processName);
2969                    return null;
2970                }
2971            } else {
2972                // When the user is explicitly starting a process, then clear its
2973                // crash count so that we won't make it bad until they see at
2974                // least one crash dialog again, and make the process good again
2975                // if it had been bad.
2976                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2977                        + "/" + info.processName);
2978                mProcessCrashTimes.remove(info.processName, info.uid);
2979                if (mBadProcesses.get(info.processName, info.uid) != null) {
2980                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2981                            UserHandle.getUserId(info.uid), info.uid,
2982                            info.processName);
2983                    mBadProcesses.remove(info.processName, info.uid);
2984                    if (app != null) {
2985                        app.bad = false;
2986                    }
2987                }
2988            }
2989        }
2990
2991        if (app == null) {
2992            checkTime(startTime, "startProcess: creating new process record");
2993            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2994            app.crashHandler = crashHandler;
2995            if (app == null) {
2996                Slog.w(TAG, "Failed making new process record for "
2997                        + processName + "/" + info.uid + " isolated=" + isolated);
2998                return null;
2999            }
3000            mProcessNames.put(processName, app.uid, app);
3001            if (isolated) {
3002                mIsolatedProcesses.put(app.uid, app);
3003            }
3004            checkTime(startTime, "startProcess: done creating new process record");
3005        } else {
3006            // If this is a new package in the process, add the package to the list
3007            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3008            checkTime(startTime, "startProcess: added package to existing proc");
3009        }
3010
3011        // If the system is not ready yet, then hold off on starting this
3012        // process until it is.
3013        if (!mProcessesReady
3014                && !isAllowedWhileBooting(info)
3015                && !allowWhileBooting) {
3016            if (!mProcessesOnHold.contains(app)) {
3017                mProcessesOnHold.add(app);
3018            }
3019            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3020            checkTime(startTime, "startProcess: returning with proc on hold");
3021            return app;
3022        }
3023
3024        checkTime(startTime, "startProcess: stepping in to startProcess");
3025        startProcessLocked(
3026                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3027        checkTime(startTime, "startProcess: done starting proc!");
3028        return (app.pid != 0) ? app : null;
3029    }
3030
3031    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3032        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3033    }
3034
3035    private final void startProcessLocked(ProcessRecord app,
3036            String hostingType, String hostingNameStr) {
3037        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3038                null /* entryPoint */, null /* entryPointArgs */);
3039    }
3040
3041    private final void startProcessLocked(ProcessRecord app, String hostingType,
3042            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3043        long startTime = SystemClock.elapsedRealtime();
3044        if (app.pid > 0 && app.pid != MY_PID) {
3045            checkTime(startTime, "startProcess: removing from pids map");
3046            synchronized (mPidsSelfLocked) {
3047                mPidsSelfLocked.remove(app.pid);
3048                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3049            }
3050            checkTime(startTime, "startProcess: done removing from pids map");
3051            app.setPid(0);
3052        }
3053
3054        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3055                "startProcessLocked removing on hold: " + app);
3056        mProcessesOnHold.remove(app);
3057
3058        checkTime(startTime, "startProcess: starting to update cpu stats");
3059        updateCpuStats();
3060        checkTime(startTime, "startProcess: done updating cpu stats");
3061
3062        try {
3063            int uid = app.uid;
3064
3065            int[] gids = null;
3066            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3067            if (!app.isolated) {
3068                int[] permGids = null;
3069                try {
3070                    checkTime(startTime, "startProcess: getting gids from package manager");
3071                    final PackageManager pm = mContext.getPackageManager();
3072                    permGids = pm.getPackageGids(app.info.packageName);
3073
3074                    if (Environment.isExternalStorageEmulated()) {
3075                        checkTime(startTime, "startProcess: checking external storage perm");
3076                        if (pm.checkPermission(
3077                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3078                                app.info.packageName) == PERMISSION_GRANTED) {
3079                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3080                        } else {
3081                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3082                        }
3083                    }
3084                } catch (PackageManager.NameNotFoundException e) {
3085                    Slog.w(TAG, "Unable to retrieve gids", e);
3086                }
3087
3088                /*
3089                 * Add shared application and profile GIDs so applications can share some
3090                 * resources like shared libraries and access user-wide resources
3091                 */
3092                if (permGids == null) {
3093                    gids = new int[2];
3094                } else {
3095                    gids = new int[permGids.length + 2];
3096                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3097                }
3098                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3099                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3100            }
3101            checkTime(startTime, "startProcess: building args");
3102            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3103                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3104                        && mTopComponent != null
3105                        && app.processName.equals(mTopComponent.getPackageName())) {
3106                    uid = 0;
3107                }
3108                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3109                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3110                    uid = 0;
3111                }
3112            }
3113            int debugFlags = 0;
3114            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3115                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3116                // Also turn on CheckJNI for debuggable apps. It's quite
3117                // awkward to turn on otherwise.
3118                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3119            }
3120            // Run the app in safe mode if its manifest requests so or the
3121            // system is booted in safe mode.
3122            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3123                mSafeMode == true) {
3124                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3125            }
3126            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3127                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3128            }
3129            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3130                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3131            }
3132            if ("1".equals(SystemProperties.get("debug.assert"))) {
3133                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3134            }
3135
3136            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3137            if (requiredAbi == null) {
3138                requiredAbi = Build.SUPPORTED_ABIS[0];
3139            }
3140
3141            String instructionSet = null;
3142            if (app.info.primaryCpuAbi != null) {
3143                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3144            }
3145
3146            // Start the process.  It will either succeed and return a result containing
3147            // the PID of the new process, or else throw a RuntimeException.
3148            boolean isActivityProcess = (entryPoint == null);
3149            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3150            checkTime(startTime, "startProcess: asking zygote to start proc");
3151            Process.ProcessStartResult startResult = Process.start(entryPoint,
3152                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3153                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3154                    entryPointArgs);
3155            checkTime(startTime, "startProcess: returned from zygote!");
3156
3157            if (app.isolated) {
3158                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3159            }
3160            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3161            checkTime(startTime, "startProcess: done updating battery stats");
3162
3163            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3164                    UserHandle.getUserId(uid), startResult.pid, uid,
3165                    app.processName, hostingType,
3166                    hostingNameStr != null ? hostingNameStr : "");
3167
3168            if (app.persistent) {
3169                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3170            }
3171
3172            checkTime(startTime, "startProcess: building log message");
3173            StringBuilder buf = mStringBuilder;
3174            buf.setLength(0);
3175            buf.append("Start proc ");
3176            buf.append(app.processName);
3177            if (!isActivityProcess) {
3178                buf.append(" [");
3179                buf.append(entryPoint);
3180                buf.append("]");
3181            }
3182            buf.append(" for ");
3183            buf.append(hostingType);
3184            if (hostingNameStr != null) {
3185                buf.append(" ");
3186                buf.append(hostingNameStr);
3187            }
3188            buf.append(": pid=");
3189            buf.append(startResult.pid);
3190            buf.append(" uid=");
3191            buf.append(uid);
3192            buf.append(" gids={");
3193            if (gids != null) {
3194                for (int gi=0; gi<gids.length; gi++) {
3195                    if (gi != 0) buf.append(", ");
3196                    buf.append(gids[gi]);
3197
3198                }
3199            }
3200            buf.append("}");
3201            if (requiredAbi != null) {
3202                buf.append(" abi=");
3203                buf.append(requiredAbi);
3204            }
3205            Slog.i(TAG, buf.toString());
3206            app.setPid(startResult.pid);
3207            app.usingWrapper = startResult.usingWrapper;
3208            app.removed = false;
3209            app.killedByAm = false;
3210            checkTime(startTime, "startProcess: starting to update pids map");
3211            synchronized (mPidsSelfLocked) {
3212                this.mPidsSelfLocked.put(startResult.pid, app);
3213                if (isActivityProcess) {
3214                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3215                    msg.obj = app;
3216                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3217                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3218                }
3219            }
3220            checkTime(startTime, "startProcess: done updating pids map");
3221        } catch (RuntimeException e) {
3222            // XXX do better error recovery.
3223            app.setPid(0);
3224            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3225            if (app.isolated) {
3226                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3227            }
3228            Slog.e(TAG, "Failure starting process " + app.processName, e);
3229        }
3230    }
3231
3232    void updateUsageStats(ActivityRecord component, boolean resumed) {
3233        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3234        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3235        if (resumed) {
3236            if (mUsageStatsService != null) {
3237                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3238                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3239            }
3240            synchronized (stats) {
3241                stats.noteActivityResumedLocked(component.app.uid);
3242            }
3243        } else {
3244            if (mUsageStatsService != null) {
3245                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3246                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3247            }
3248            synchronized (stats) {
3249                stats.noteActivityPausedLocked(component.app.uid);
3250            }
3251        }
3252    }
3253
3254    Intent getHomeIntent() {
3255        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3256        intent.setComponent(mTopComponent);
3257        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3258            intent.addCategory(Intent.CATEGORY_HOME);
3259        }
3260        return intent;
3261    }
3262
3263    boolean startHomeActivityLocked(int userId) {
3264        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3265                && mTopAction == null) {
3266            // We are running in factory test mode, but unable to find
3267            // the factory test app, so just sit around displaying the
3268            // error message and don't try to start anything.
3269            return false;
3270        }
3271        Intent intent = getHomeIntent();
3272        ActivityInfo aInfo =
3273            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3274        if (aInfo != null) {
3275            intent.setComponent(new ComponentName(
3276                    aInfo.applicationInfo.packageName, aInfo.name));
3277            // Don't do this if the home app is currently being
3278            // instrumented.
3279            aInfo = new ActivityInfo(aInfo);
3280            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3281            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3282                    aInfo.applicationInfo.uid, true);
3283            if (app == null || app.instrumentationClass == null) {
3284                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3285                mStackSupervisor.startHomeActivity(intent, aInfo);
3286            }
3287        }
3288
3289        return true;
3290    }
3291
3292    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3293        ActivityInfo ai = null;
3294        ComponentName comp = intent.getComponent();
3295        try {
3296            if (comp != null) {
3297                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3298            } else {
3299                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3300                        intent,
3301                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3302                            flags, userId);
3303
3304                if (info != null) {
3305                    ai = info.activityInfo;
3306                }
3307            }
3308        } catch (RemoteException e) {
3309            // ignore
3310        }
3311
3312        return ai;
3313    }
3314
3315    /**
3316     * Starts the "new version setup screen" if appropriate.
3317     */
3318    void startSetupActivityLocked() {
3319        // Only do this once per boot.
3320        if (mCheckedForSetup) {
3321            return;
3322        }
3323
3324        // We will show this screen if the current one is a different
3325        // version than the last one shown, and we are not running in
3326        // low-level factory test mode.
3327        final ContentResolver resolver = mContext.getContentResolver();
3328        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3329                Settings.Global.getInt(resolver,
3330                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3331            mCheckedForSetup = true;
3332
3333            // See if we should be showing the platform update setup UI.
3334            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3335            List<ResolveInfo> ris = mContext.getPackageManager()
3336                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3337
3338            // We don't allow third party apps to replace this.
3339            ResolveInfo ri = null;
3340            for (int i=0; ris != null && i<ris.size(); i++) {
3341                if ((ris.get(i).activityInfo.applicationInfo.flags
3342                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3343                    ri = ris.get(i);
3344                    break;
3345                }
3346            }
3347
3348            if (ri != null) {
3349                String vers = ri.activityInfo.metaData != null
3350                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3351                        : null;
3352                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3353                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3354                            Intent.METADATA_SETUP_VERSION);
3355                }
3356                String lastVers = Settings.Secure.getString(
3357                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3358                if (vers != null && !vers.equals(lastVers)) {
3359                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3360                    intent.setComponent(new ComponentName(
3361                            ri.activityInfo.packageName, ri.activityInfo.name));
3362                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3363                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3364                            null);
3365                }
3366            }
3367        }
3368    }
3369
3370    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3371        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3372    }
3373
3374    void enforceNotIsolatedCaller(String caller) {
3375        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3376            throw new SecurityException("Isolated process not allowed to call " + caller);
3377        }
3378    }
3379
3380    void enforceShellRestriction(String restriction, int userHandle) {
3381        if (Binder.getCallingUid() == Process.SHELL_UID) {
3382            if (userHandle < 0
3383                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3384                throw new SecurityException("Shell does not have permission to access user "
3385                        + userHandle);
3386            }
3387        }
3388    }
3389
3390    @Override
3391    public int getFrontActivityScreenCompatMode() {
3392        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3393        synchronized (this) {
3394            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3395        }
3396    }
3397
3398    @Override
3399    public void setFrontActivityScreenCompatMode(int mode) {
3400        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3401                "setFrontActivityScreenCompatMode");
3402        synchronized (this) {
3403            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3404        }
3405    }
3406
3407    @Override
3408    public int getPackageScreenCompatMode(String packageName) {
3409        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3410        synchronized (this) {
3411            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3412        }
3413    }
3414
3415    @Override
3416    public void setPackageScreenCompatMode(String packageName, int mode) {
3417        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3418                "setPackageScreenCompatMode");
3419        synchronized (this) {
3420            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3421        }
3422    }
3423
3424    @Override
3425    public boolean getPackageAskScreenCompat(String packageName) {
3426        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3427        synchronized (this) {
3428            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3429        }
3430    }
3431
3432    @Override
3433    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3434        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3435                "setPackageAskScreenCompat");
3436        synchronized (this) {
3437            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3438        }
3439    }
3440
3441    private void dispatchProcessesChanged() {
3442        int N;
3443        synchronized (this) {
3444            N = mPendingProcessChanges.size();
3445            if (mActiveProcessChanges.length < N) {
3446                mActiveProcessChanges = new ProcessChangeItem[N];
3447            }
3448            mPendingProcessChanges.toArray(mActiveProcessChanges);
3449            mAvailProcessChanges.addAll(mPendingProcessChanges);
3450            mPendingProcessChanges.clear();
3451            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3452        }
3453
3454        int i = mProcessObservers.beginBroadcast();
3455        while (i > 0) {
3456            i--;
3457            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3458            if (observer != null) {
3459                try {
3460                    for (int j=0; j<N; j++) {
3461                        ProcessChangeItem item = mActiveProcessChanges[j];
3462                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3463                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3464                                    + item.pid + " uid=" + item.uid + ": "
3465                                    + item.foregroundActivities);
3466                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3467                                    item.foregroundActivities);
3468                        }
3469                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3470                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3471                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3472                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3473                        }
3474                    }
3475                } catch (RemoteException e) {
3476                }
3477            }
3478        }
3479        mProcessObservers.finishBroadcast();
3480    }
3481
3482    private void dispatchProcessDied(int pid, int uid) {
3483        int i = mProcessObservers.beginBroadcast();
3484        while (i > 0) {
3485            i--;
3486            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3487            if (observer != null) {
3488                try {
3489                    observer.onProcessDied(pid, uid);
3490                } catch (RemoteException e) {
3491                }
3492            }
3493        }
3494        mProcessObservers.finishBroadcast();
3495    }
3496
3497    @Override
3498    public final int startActivity(IApplicationThread caller, String callingPackage,
3499            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3500            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3501        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3502            resultWho, requestCode, startFlags, profilerInfo, options,
3503            UserHandle.getCallingUserId());
3504    }
3505
3506    @Override
3507    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3508            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3509            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3510        enforceNotIsolatedCaller("startActivity");
3511        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3512                false, ALLOW_FULL_ONLY, "startActivity", null);
3513        // TODO: Switch to user app stacks here.
3514        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3515                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3516                profilerInfo, null, null, options, userId, null, null);
3517    }
3518
3519    @Override
3520    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3521            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3522            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3523
3524        // This is very dangerous -- it allows you to perform a start activity (including
3525        // permission grants) as any app that may launch one of your own activities.  So
3526        // we will only allow this to be done from activities that are part of the core framework,
3527        // and then only when they are running as the system.
3528        final ActivityRecord sourceRecord;
3529        final int targetUid;
3530        final String targetPackage;
3531        synchronized (this) {
3532            if (resultTo == null) {
3533                throw new SecurityException("Must be called from an activity");
3534            }
3535            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3536            if (sourceRecord == null) {
3537                throw new SecurityException("Called with bad activity token: " + resultTo);
3538            }
3539            if (!sourceRecord.info.packageName.equals("android")) {
3540                throw new SecurityException(
3541                        "Must be called from an activity that is declared in the android package");
3542            }
3543            if (sourceRecord.app == null) {
3544                throw new SecurityException("Called without a process attached to activity");
3545            }
3546            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3547                // This is still okay, as long as this activity is running under the
3548                // uid of the original calling activity.
3549                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3550                    throw new SecurityException(
3551                            "Calling activity in uid " + sourceRecord.app.uid
3552                                    + " must be system uid or original calling uid "
3553                                    + sourceRecord.launchedFromUid);
3554                }
3555            }
3556            targetUid = sourceRecord.launchedFromUid;
3557            targetPackage = sourceRecord.launchedFromPackage;
3558        }
3559
3560        // TODO: Switch to user app stacks here.
3561        try {
3562            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3563                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3564                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3565            return ret;
3566        } catch (SecurityException e) {
3567            // XXX need to figure out how to propagate to original app.
3568            // A SecurityException here is generally actually a fault of the original
3569            // calling activity (such as a fairly granting permissions), so propagate it
3570            // back to them.
3571            /*
3572            StringBuilder msg = new StringBuilder();
3573            msg.append("While launching");
3574            msg.append(intent.toString());
3575            msg.append(": ");
3576            msg.append(e.getMessage());
3577            */
3578            throw e;
3579        }
3580    }
3581
3582    @Override
3583    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3584            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3585            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3586        enforceNotIsolatedCaller("startActivityAndWait");
3587        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3588                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3589        WaitResult res = new WaitResult();
3590        // TODO: Switch to user app stacks here.
3591        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3592                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3593                options, userId, null, null);
3594        return res;
3595    }
3596
3597    @Override
3598    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3599            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3600            int startFlags, Configuration config, Bundle options, int userId) {
3601        enforceNotIsolatedCaller("startActivityWithConfig");
3602        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3603                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3604        // TODO: Switch to user app stacks here.
3605        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3606                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3607                null, null, config, options, userId, null, null);
3608        return ret;
3609    }
3610
3611    @Override
3612    public int startActivityIntentSender(IApplicationThread caller,
3613            IntentSender intent, Intent fillInIntent, String resolvedType,
3614            IBinder resultTo, String resultWho, int requestCode,
3615            int flagsMask, int flagsValues, Bundle options) {
3616        enforceNotIsolatedCaller("startActivityIntentSender");
3617        // Refuse possible leaked file descriptors
3618        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3619            throw new IllegalArgumentException("File descriptors passed in Intent");
3620        }
3621
3622        IIntentSender sender = intent.getTarget();
3623        if (!(sender instanceof PendingIntentRecord)) {
3624            throw new IllegalArgumentException("Bad PendingIntent object");
3625        }
3626
3627        PendingIntentRecord pir = (PendingIntentRecord)sender;
3628
3629        synchronized (this) {
3630            // If this is coming from the currently resumed activity, it is
3631            // effectively saying that app switches are allowed at this point.
3632            final ActivityStack stack = getFocusedStack();
3633            if (stack.mResumedActivity != null &&
3634                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3635                mAppSwitchesAllowedTime = 0;
3636            }
3637        }
3638        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3639                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3640        return ret;
3641    }
3642
3643    @Override
3644    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3645            Intent intent, String resolvedType, IVoiceInteractionSession session,
3646            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3647            Bundle options, int userId) {
3648        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3649                != PackageManager.PERMISSION_GRANTED) {
3650            String msg = "Permission Denial: startVoiceActivity() from pid="
3651                    + Binder.getCallingPid()
3652                    + ", uid=" + Binder.getCallingUid()
3653                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3654            Slog.w(TAG, msg);
3655            throw new SecurityException(msg);
3656        }
3657        if (session == null || interactor == null) {
3658            throw new NullPointerException("null session or interactor");
3659        }
3660        userId = handleIncomingUser(callingPid, callingUid, userId,
3661                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3662        // TODO: Switch to user app stacks here.
3663        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3664                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3665                null, options, userId, null, null);
3666    }
3667
3668    @Override
3669    public boolean startNextMatchingActivity(IBinder callingActivity,
3670            Intent intent, Bundle options) {
3671        // Refuse possible leaked file descriptors
3672        if (intent != null && intent.hasFileDescriptors() == true) {
3673            throw new IllegalArgumentException("File descriptors passed in Intent");
3674        }
3675
3676        synchronized (this) {
3677            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3678            if (r == null) {
3679                ActivityOptions.abort(options);
3680                return false;
3681            }
3682            if (r.app == null || r.app.thread == null) {
3683                // The caller is not running...  d'oh!
3684                ActivityOptions.abort(options);
3685                return false;
3686            }
3687            intent = new Intent(intent);
3688            // The caller is not allowed to change the data.
3689            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3690            // And we are resetting to find the next component...
3691            intent.setComponent(null);
3692
3693            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3694
3695            ActivityInfo aInfo = null;
3696            try {
3697                List<ResolveInfo> resolves =
3698                    AppGlobals.getPackageManager().queryIntentActivities(
3699                            intent, r.resolvedType,
3700                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3701                            UserHandle.getCallingUserId());
3702
3703                // Look for the original activity in the list...
3704                final int N = resolves != null ? resolves.size() : 0;
3705                for (int i=0; i<N; i++) {
3706                    ResolveInfo rInfo = resolves.get(i);
3707                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3708                            && rInfo.activityInfo.name.equals(r.info.name)) {
3709                        // We found the current one...  the next matching is
3710                        // after it.
3711                        i++;
3712                        if (i<N) {
3713                            aInfo = resolves.get(i).activityInfo;
3714                        }
3715                        if (debug) {
3716                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3717                                    + "/" + r.info.name);
3718                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3719                                    + "/" + aInfo.name);
3720                        }
3721                        break;
3722                    }
3723                }
3724            } catch (RemoteException e) {
3725            }
3726
3727            if (aInfo == null) {
3728                // Nobody who is next!
3729                ActivityOptions.abort(options);
3730                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3731                return false;
3732            }
3733
3734            intent.setComponent(new ComponentName(
3735                    aInfo.applicationInfo.packageName, aInfo.name));
3736            intent.setFlags(intent.getFlags()&~(
3737                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3738                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3739                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3740                    Intent.FLAG_ACTIVITY_NEW_TASK));
3741
3742            // Okay now we need to start the new activity, replacing the
3743            // currently running activity.  This is a little tricky because
3744            // we want to start the new one as if the current one is finished,
3745            // but not finish the current one first so that there is no flicker.
3746            // And thus...
3747            final boolean wasFinishing = r.finishing;
3748            r.finishing = true;
3749
3750            // Propagate reply information over to the new activity.
3751            final ActivityRecord resultTo = r.resultTo;
3752            final String resultWho = r.resultWho;
3753            final int requestCode = r.requestCode;
3754            r.resultTo = null;
3755            if (resultTo != null) {
3756                resultTo.removeResultsLocked(r, resultWho, requestCode);
3757            }
3758
3759            final long origId = Binder.clearCallingIdentity();
3760            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3761                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3762                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3763                    options, false, null, null, null);
3764            Binder.restoreCallingIdentity(origId);
3765
3766            r.finishing = wasFinishing;
3767            if (res != ActivityManager.START_SUCCESS) {
3768                return false;
3769            }
3770            return true;
3771        }
3772    }
3773
3774    @Override
3775    public final int startActivityFromRecents(int taskId, Bundle options) {
3776        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3777            String msg = "Permission Denial: startActivityFromRecents called without " +
3778                    START_TASKS_FROM_RECENTS;
3779            Slog.w(TAG, msg);
3780            throw new SecurityException(msg);
3781        }
3782        return startActivityFromRecentsInner(taskId, options);
3783    }
3784
3785    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3786        final TaskRecord task;
3787        final int callingUid;
3788        final String callingPackage;
3789        final Intent intent;
3790        final int userId;
3791        synchronized (this) {
3792            task = recentTaskForIdLocked(taskId);
3793            if (task == null) {
3794                throw new IllegalArgumentException("Task " + taskId + " not found.");
3795            }
3796            callingUid = task.mCallingUid;
3797            callingPackage = task.mCallingPackage;
3798            intent = task.intent;
3799            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3800            userId = task.userId;
3801        }
3802        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3803                options, userId, null, task);
3804    }
3805
3806    final int startActivityInPackage(int uid, String callingPackage,
3807            Intent intent, String resolvedType, IBinder resultTo,
3808            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3809            IActivityContainer container, TaskRecord inTask) {
3810
3811        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3812                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3813
3814        // TODO: Switch to user app stacks here.
3815        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3816                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3817                null, null, null, options, userId, container, inTask);
3818        return ret;
3819    }
3820
3821    @Override
3822    public final int startActivities(IApplicationThread caller, String callingPackage,
3823            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3824            int userId) {
3825        enforceNotIsolatedCaller("startActivities");
3826        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3827                false, ALLOW_FULL_ONLY, "startActivity", null);
3828        // TODO: Switch to user app stacks here.
3829        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3830                resolvedTypes, resultTo, options, userId);
3831        return ret;
3832    }
3833
3834    final int startActivitiesInPackage(int uid, String callingPackage,
3835            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3836            Bundle options, int userId) {
3837
3838        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3839                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3840        // TODO: Switch to user app stacks here.
3841        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3842                resultTo, options, userId);
3843        return ret;
3844    }
3845
3846    //explicitly remove thd old information in mRecentTasks when removing existing user.
3847    private void removeRecentTasksForUserLocked(int userId) {
3848        if(userId <= 0) {
3849            Slog.i(TAG, "Can't remove recent task on user " + userId);
3850            return;
3851        }
3852
3853        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3854            TaskRecord tr = mRecentTasks.get(i);
3855            if (tr.userId == userId) {
3856                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3857                        + " when finishing user" + userId);
3858                mRecentTasks.remove(i);
3859                tr.removedFromRecents(mTaskPersister);
3860            }
3861        }
3862
3863        // Remove tasks from persistent storage.
3864        mTaskPersister.wakeup(null, true);
3865    }
3866
3867    /**
3868     * Update the recent tasks lists: make sure tasks should still be here (their
3869     * applications / activities still exist), update their availability, fixup ordering
3870     * of affiliations.
3871     */
3872    void cleanupRecentTasksLocked(int userId) {
3873        if (mRecentTasks == null) {
3874            // Happens when called from the packagemanager broadcast before boot.
3875            return;
3876        }
3877
3878        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3879        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3880        final IPackageManager pm = AppGlobals.getPackageManager();
3881        final ActivityInfo dummyAct = new ActivityInfo();
3882        final ApplicationInfo dummyApp = new ApplicationInfo();
3883
3884        int N = mRecentTasks.size();
3885
3886        int[] users = userId == UserHandle.USER_ALL
3887                ? getUsersLocked() : new int[] { userId };
3888        for (int user : users) {
3889            for (int i = 0; i < N; i++) {
3890                TaskRecord task = mRecentTasks.get(i);
3891                if (task.userId != user) {
3892                    // Only look at tasks for the user ID of interest.
3893                    continue;
3894                }
3895                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3896                    // This situation is broken, and we should just get rid of it now.
3897                    mRecentTasks.remove(i);
3898                    task.removedFromRecents(mTaskPersister);
3899                    i--;
3900                    N--;
3901                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3902                    continue;
3903                }
3904                // Check whether this activity is currently available.
3905                if (task.realActivity != null) {
3906                    ActivityInfo ai = availActCache.get(task.realActivity);
3907                    if (ai == null) {
3908                        try {
3909                            ai = pm.getActivityInfo(task.realActivity,
3910                                    PackageManager.GET_UNINSTALLED_PACKAGES
3911                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3912                        } catch (RemoteException e) {
3913                            // Will never happen.
3914                            continue;
3915                        }
3916                        if (ai == null) {
3917                            ai = dummyAct;
3918                        }
3919                        availActCache.put(task.realActivity, ai);
3920                    }
3921                    if (ai == dummyAct) {
3922                        // This could be either because the activity no longer exists, or the
3923                        // app is temporarily gone.  For the former we want to remove the recents
3924                        // entry; for the latter we want to mark it as unavailable.
3925                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3926                        if (app == null) {
3927                            try {
3928                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3929                                        PackageManager.GET_UNINSTALLED_PACKAGES
3930                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3931                            } catch (RemoteException e) {
3932                                // Will never happen.
3933                                continue;
3934                            }
3935                            if (app == null) {
3936                                app = dummyApp;
3937                            }
3938                            availAppCache.put(task.realActivity.getPackageName(), app);
3939                        }
3940                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3941                            // Doesn't exist any more!  Good-bye.
3942                            mRecentTasks.remove(i);
3943                            task.removedFromRecents(mTaskPersister);
3944                            i--;
3945                            N--;
3946                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3947                            continue;
3948                        } else {
3949                            // Otherwise just not available for now.
3950                            if (task.isAvailable) {
3951                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3952                                        + task);
3953                            }
3954                            task.isAvailable = false;
3955                        }
3956                    } else {
3957                        if (!ai.enabled || !ai.applicationInfo.enabled
3958                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3959                            if (task.isAvailable) {
3960                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3961                                        + task + " (enabled=" + ai.enabled + "/"
3962                                        + ai.applicationInfo.enabled +  " flags="
3963                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3964                            }
3965                            task.isAvailable = false;
3966                        } else {
3967                            if (!task.isAvailable) {
3968                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3969                                        + task);
3970                            }
3971                            task.isAvailable = true;
3972                        }
3973                    }
3974                }
3975            }
3976        }
3977
3978        // Verify the affiliate chain for each task.
3979        for (int i = 0; i < N; ) {
3980            TaskRecord task = mRecentTasks.remove(i);
3981            if (mTmpRecents.contains(task)) {
3982                continue;
3983            }
3984            int affiliatedTaskId = task.mAffiliatedTaskId;
3985            while (true) {
3986                TaskRecord next = task.mNextAffiliate;
3987                if (next == null) {
3988                    break;
3989                }
3990                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3991                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3992                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3993                    task.setNextAffiliate(null);
3994                    if (next.mPrevAffiliate == task) {
3995                        next.setPrevAffiliate(null);
3996                    }
3997                    break;
3998                }
3999                if (next.mPrevAffiliate != task) {
4000                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
4001                            next.mPrevAffiliate + " task=" + task);
4002                    next.setPrevAffiliate(null);
4003                    task.setNextAffiliate(null);
4004                    break;
4005                }
4006                if (!mRecentTasks.contains(next)) {
4007                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
4008                    task.setNextAffiliate(null);
4009                    // We know that next.mPrevAffiliate is always task, from above, so clear
4010                    // its previous affiliate.
4011                    next.setPrevAffiliate(null);
4012                    break;
4013                }
4014                task = next;
4015            }
4016            // task is now the end of the list
4017            do {
4018                mRecentTasks.remove(task);
4019                mRecentTasks.add(i++, task);
4020                mTmpRecents.add(task);
4021                task.inRecents = true;
4022            } while ((task = task.mPrevAffiliate) != null);
4023        }
4024        mTmpRecents.clear();
4025        // mRecentTasks is now in sorted, affiliated order.
4026    }
4027
4028    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4029        int N = mRecentTasks.size();
4030        TaskRecord top = task;
4031        int topIndex = taskIndex;
4032        while (top.mNextAffiliate != null && topIndex > 0) {
4033            top = top.mNextAffiliate;
4034            topIndex--;
4035        }
4036        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4037                + topIndex + " from intial " + taskIndex);
4038        // Find the end of the chain, doing a sanity check along the way.
4039        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4040        int endIndex = topIndex;
4041        TaskRecord prev = top;
4042        while (endIndex < N) {
4043            TaskRecord cur = mRecentTasks.get(endIndex);
4044            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4045                    + endIndex + " " + cur);
4046            if (cur == top) {
4047                // Verify start of the chain.
4048                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4049                    Slog.wtf(TAG, "Bad chain @" + endIndex
4050                            + ": first task has next affiliate: " + prev);
4051                    sane = false;
4052                    break;
4053                }
4054            } else {
4055                // Verify middle of the chain's next points back to the one before.
4056                if (cur.mNextAffiliate != prev
4057                        || cur.mNextAffiliateTaskId != prev.taskId) {
4058                    Slog.wtf(TAG, "Bad chain @" + endIndex
4059                            + ": middle task " + cur + " @" + endIndex
4060                            + " has bad next affiliate "
4061                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4062                            + ", expected " + prev);
4063                    sane = false;
4064                    break;
4065                }
4066            }
4067            if (cur.mPrevAffiliateTaskId == -1) {
4068                // Chain ends here.
4069                if (cur.mPrevAffiliate != null) {
4070                    Slog.wtf(TAG, "Bad chain @" + endIndex
4071                            + ": last task " + cur + " has previous affiliate "
4072                            + cur.mPrevAffiliate);
4073                    sane = false;
4074                }
4075                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4076                break;
4077            } else {
4078                // Verify middle of the chain's prev points to a valid item.
4079                if (cur.mPrevAffiliate == null) {
4080                    Slog.wtf(TAG, "Bad chain @" + endIndex
4081                            + ": task " + cur + " has previous affiliate "
4082                            + cur.mPrevAffiliate + " but should be id "
4083                            + cur.mPrevAffiliate);
4084                    sane = false;
4085                    break;
4086                }
4087            }
4088            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4089                Slog.wtf(TAG, "Bad chain @" + endIndex
4090                        + ": task " + cur + " has affiliated id "
4091                        + cur.mAffiliatedTaskId + " but should be "
4092                        + task.mAffiliatedTaskId);
4093                sane = false;
4094                break;
4095            }
4096            prev = cur;
4097            endIndex++;
4098            if (endIndex >= N) {
4099                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4100                        + ": last task " + prev);
4101                sane = false;
4102                break;
4103            }
4104        }
4105        if (sane) {
4106            if (endIndex < taskIndex) {
4107                Slog.wtf(TAG, "Bad chain @" + endIndex
4108                        + ": did not extend to task " + task + " @" + taskIndex);
4109                sane = false;
4110            }
4111        }
4112        if (sane) {
4113            // All looks good, we can just move all of the affiliated tasks
4114            // to the top.
4115            for (int i=topIndex; i<=endIndex; i++) {
4116                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4117                        + " from " + i + " to " + (i-topIndex));
4118                TaskRecord cur = mRecentTasks.remove(i);
4119                mRecentTasks.add(i-topIndex, cur);
4120            }
4121            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4122                    + " to " + endIndex);
4123            return true;
4124        }
4125
4126        // Whoops, couldn't do it.
4127        return false;
4128    }
4129
4130    final void addRecentTaskLocked(TaskRecord task) {
4131        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4132                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4133
4134        int N = mRecentTasks.size();
4135        // Quick case: check if the top-most recent task is the same.
4136        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4137            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4138            return;
4139        }
4140        // Another quick case: check if this is part of a set of affiliated
4141        // tasks that are at the top.
4142        if (isAffiliated && N > 0 && task.inRecents
4143                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4144            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4145                    + " at top when adding " + task);
4146            return;
4147        }
4148        // Another quick case: never add voice sessions.
4149        if (task.voiceSession != null) {
4150            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4151            return;
4152        }
4153
4154        boolean needAffiliationFix = false;
4155
4156        // Slightly less quick case: the task is already in recents, so all we need
4157        // to do is move it.
4158        if (task.inRecents) {
4159            int taskIndex = mRecentTasks.indexOf(task);
4160            if (taskIndex >= 0) {
4161                if (!isAffiliated) {
4162                    // Simple case: this is not an affiliated task, so we just move it to the front.
4163                    mRecentTasks.remove(taskIndex);
4164                    mRecentTasks.add(0, task);
4165                    notifyTaskPersisterLocked(task, false);
4166                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4167                            + " from " + taskIndex);
4168                    return;
4169                } else {
4170                    // More complicated: need to keep all affiliated tasks together.
4171                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4172                        // All went well.
4173                        return;
4174                    }
4175
4176                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4177                    // everything and then go through our general path of adding a new task.
4178                    needAffiliationFix = true;
4179                }
4180            } else {
4181                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4182                needAffiliationFix = true;
4183            }
4184        }
4185
4186        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4187        trimRecentsForTask(task, true);
4188
4189        N = mRecentTasks.size();
4190        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4191            final TaskRecord tr = mRecentTasks.remove(N - 1);
4192            tr.removedFromRecents(mTaskPersister);
4193            N--;
4194        }
4195        task.inRecents = true;
4196        if (!isAffiliated || needAffiliationFix) {
4197            // If this is a simple non-affiliated task, or we had some failure trying to
4198            // handle it as part of an affilated task, then just place it at the top.
4199            mRecentTasks.add(0, task);
4200        } else if (isAffiliated) {
4201            // If this is a new affiliated task, then move all of the affiliated tasks
4202            // to the front and insert this new one.
4203            TaskRecord other = task.mNextAffiliate;
4204            if (other == null) {
4205                other = task.mPrevAffiliate;
4206            }
4207            if (other != null) {
4208                int otherIndex = mRecentTasks.indexOf(other);
4209                if (otherIndex >= 0) {
4210                    // Insert new task at appropriate location.
4211                    int taskIndex;
4212                    if (other == task.mNextAffiliate) {
4213                        // We found the index of our next affiliation, which is who is
4214                        // before us in the list, so add after that point.
4215                        taskIndex = otherIndex+1;
4216                    } else {
4217                        // We found the index of our previous affiliation, which is who is
4218                        // after us in the list, so add at their position.
4219                        taskIndex = otherIndex;
4220                    }
4221                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4222                            + taskIndex + ": " + task);
4223                    mRecentTasks.add(taskIndex, task);
4224
4225                    // Now move everything to the front.
4226                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4227                        // All went well.
4228                        return;
4229                    }
4230
4231                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4232                    // everything and then go through our general path of adding a new task.
4233                    needAffiliationFix = true;
4234                } else {
4235                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4236                            + other);
4237                    needAffiliationFix = true;
4238                }
4239            } else {
4240                if (DEBUG_RECENTS) Slog.d(TAG,
4241                        "addRecent: adding affiliated task without next/prev:" + task);
4242                needAffiliationFix = true;
4243            }
4244        }
4245        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4246
4247        if (needAffiliationFix) {
4248            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4249            cleanupRecentTasksLocked(task.userId);
4250        }
4251    }
4252
4253    /**
4254     * If needed, remove oldest existing entries in recents that are for the same kind
4255     * of task as the given one.
4256     */
4257    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4258        int N = mRecentTasks.size();
4259        final Intent intent = task.intent;
4260        final boolean document = intent != null && intent.isDocument();
4261
4262        int maxRecents = task.maxRecents - 1;
4263        for (int i=0; i<N; i++) {
4264            final TaskRecord tr = mRecentTasks.get(i);
4265            if (task != tr) {
4266                if (task.userId != tr.userId) {
4267                    continue;
4268                }
4269                if (i > MAX_RECENT_BITMAPS) {
4270                    tr.freeLastThumbnail();
4271                }
4272                final Intent trIntent = tr.intent;
4273                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4274                    (intent == null || !intent.filterEquals(trIntent))) {
4275                    continue;
4276                }
4277                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4278                if (document && trIsDocument) {
4279                    // These are the same document activity (not necessarily the same doc).
4280                    if (maxRecents > 0) {
4281                        --maxRecents;
4282                        continue;
4283                    }
4284                    // Hit the maximum number of documents for this task. Fall through
4285                    // and remove this document from recents.
4286                } else if (document || trIsDocument) {
4287                    // Only one of these is a document. Not the droid we're looking for.
4288                    continue;
4289                }
4290            }
4291
4292            if (!doTrim) {
4293                // If the caller is not actually asking for a trim, just tell them we reached
4294                // a point where the trim would happen.
4295                return i;
4296            }
4297
4298            // Either task and tr are the same or, their affinities match or their intents match
4299            // and neither of them is a document, or they are documents using the same activity
4300            // and their maxRecents has been reached.
4301            tr.disposeThumbnail();
4302            mRecentTasks.remove(i);
4303            if (task != tr) {
4304                tr.removedFromRecents(mTaskPersister);
4305            }
4306            i--;
4307            N--;
4308            if (task.intent == null) {
4309                // If the new recent task we are adding is not fully
4310                // specified, then replace it with the existing recent task.
4311                task = tr;
4312            }
4313            notifyTaskPersisterLocked(tr, false);
4314        }
4315
4316        return -1;
4317    }
4318
4319    @Override
4320    public void reportActivityFullyDrawn(IBinder token) {
4321        synchronized (this) {
4322            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4323            if (r == null) {
4324                return;
4325            }
4326            r.reportFullyDrawnLocked();
4327        }
4328    }
4329
4330    @Override
4331    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4332        synchronized (this) {
4333            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4334            if (r == null) {
4335                return;
4336            }
4337            final long origId = Binder.clearCallingIdentity();
4338            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4339            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4340                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4341            if (config != null) {
4342                r.frozenBeforeDestroy = true;
4343                if (!updateConfigurationLocked(config, r, false, false)) {
4344                    mStackSupervisor.resumeTopActivitiesLocked();
4345                }
4346            }
4347            Binder.restoreCallingIdentity(origId);
4348        }
4349    }
4350
4351    @Override
4352    public int getRequestedOrientation(IBinder token) {
4353        synchronized (this) {
4354            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4355            if (r == null) {
4356                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4357            }
4358            return mWindowManager.getAppOrientation(r.appToken);
4359        }
4360    }
4361
4362    /**
4363     * This is the internal entry point for handling Activity.finish().
4364     *
4365     * @param token The Binder token referencing the Activity we want to finish.
4366     * @param resultCode Result code, if any, from this Activity.
4367     * @param resultData Result data (Intent), if any, from this Activity.
4368     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4369     *            the root Activity in the task.
4370     *
4371     * @return Returns true if the activity successfully finished, or false if it is still running.
4372     */
4373    @Override
4374    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4375            boolean finishTask) {
4376        // Refuse possible leaked file descriptors
4377        if (resultData != null && resultData.hasFileDescriptors() == true) {
4378            throw new IllegalArgumentException("File descriptors passed in Intent");
4379        }
4380
4381        synchronized(this) {
4382            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4383            if (r == null) {
4384                return true;
4385            }
4386            // Keep track of the root activity of the task before we finish it
4387            TaskRecord tr = r.task;
4388            ActivityRecord rootR = tr.getRootActivity();
4389            // Do not allow task to finish in Lock Task mode.
4390            if (tr == mStackSupervisor.mLockTaskModeTask) {
4391                if (rootR == r) {
4392                    mStackSupervisor.showLockTaskToast();
4393                    return false;
4394                }
4395            }
4396            if (mController != null) {
4397                // Find the first activity that is not finishing.
4398                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4399                if (next != null) {
4400                    // ask watcher if this is allowed
4401                    boolean resumeOK = true;
4402                    try {
4403                        resumeOK = mController.activityResuming(next.packageName);
4404                    } catch (RemoteException e) {
4405                        mController = null;
4406                        Watchdog.getInstance().setActivityController(null);
4407                    }
4408
4409                    if (!resumeOK) {
4410                        return false;
4411                    }
4412                }
4413            }
4414            final long origId = Binder.clearCallingIdentity();
4415            try {
4416                boolean res;
4417                if (finishTask && r == rootR) {
4418                    // If requested, remove the task that is associated to this activity only if it
4419                    // was the root activity in the task.  The result code and data is ignored because
4420                    // we don't support returning them across task boundaries.
4421                    res = removeTaskByIdLocked(tr.taskId, 0);
4422                } else {
4423                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4424                            resultData, "app-request", true);
4425                }
4426                return res;
4427            } finally {
4428                Binder.restoreCallingIdentity(origId);
4429            }
4430        }
4431    }
4432
4433    @Override
4434    public final void finishHeavyWeightApp() {
4435        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4436                != PackageManager.PERMISSION_GRANTED) {
4437            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4438                    + Binder.getCallingPid()
4439                    + ", uid=" + Binder.getCallingUid()
4440                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4441            Slog.w(TAG, msg);
4442            throw new SecurityException(msg);
4443        }
4444
4445        synchronized(this) {
4446            if (mHeavyWeightProcess == null) {
4447                return;
4448            }
4449
4450            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4451                    mHeavyWeightProcess.activities);
4452            for (int i=0; i<activities.size(); i++) {
4453                ActivityRecord r = activities.get(i);
4454                if (!r.finishing) {
4455                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4456                            null, "finish-heavy", true);
4457                }
4458            }
4459
4460            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4461                    mHeavyWeightProcess.userId, 0));
4462            mHeavyWeightProcess = null;
4463        }
4464    }
4465
4466    @Override
4467    public void crashApplication(int uid, int initialPid, String packageName,
4468            String message) {
4469        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4470                != PackageManager.PERMISSION_GRANTED) {
4471            String msg = "Permission Denial: crashApplication() from pid="
4472                    + Binder.getCallingPid()
4473                    + ", uid=" + Binder.getCallingUid()
4474                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4475            Slog.w(TAG, msg);
4476            throw new SecurityException(msg);
4477        }
4478
4479        synchronized(this) {
4480            ProcessRecord proc = null;
4481
4482            // Figure out which process to kill.  We don't trust that initialPid
4483            // still has any relation to current pids, so must scan through the
4484            // list.
4485            synchronized (mPidsSelfLocked) {
4486                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4487                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4488                    if (p.uid != uid) {
4489                        continue;
4490                    }
4491                    if (p.pid == initialPid) {
4492                        proc = p;
4493                        break;
4494                    }
4495                    if (p.pkgList.containsKey(packageName)) {
4496                        proc = p;
4497                    }
4498                }
4499            }
4500
4501            if (proc == null) {
4502                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4503                        + " initialPid=" + initialPid
4504                        + " packageName=" + packageName);
4505                return;
4506            }
4507
4508            if (proc.thread != null) {
4509                if (proc.pid == Process.myPid()) {
4510                    Log.w(TAG, "crashApplication: trying to crash self!");
4511                    return;
4512                }
4513                long ident = Binder.clearCallingIdentity();
4514                try {
4515                    proc.thread.scheduleCrash(message);
4516                } catch (RemoteException e) {
4517                }
4518                Binder.restoreCallingIdentity(ident);
4519            }
4520        }
4521    }
4522
4523    @Override
4524    public final void finishSubActivity(IBinder token, String resultWho,
4525            int requestCode) {
4526        synchronized(this) {
4527            final long origId = Binder.clearCallingIdentity();
4528            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4529            if (r != null) {
4530                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4531            }
4532            Binder.restoreCallingIdentity(origId);
4533        }
4534    }
4535
4536    @Override
4537    public boolean finishActivityAffinity(IBinder token) {
4538        synchronized(this) {
4539            final long origId = Binder.clearCallingIdentity();
4540            try {
4541                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4542
4543                ActivityRecord rootR = r.task.getRootActivity();
4544                // Do not allow task to finish in Lock Task mode.
4545                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4546                    if (rootR == r) {
4547                        mStackSupervisor.showLockTaskToast();
4548                        return false;
4549                    }
4550                }
4551                boolean res = false;
4552                if (r != null) {
4553                    res = r.task.stack.finishActivityAffinityLocked(r);
4554                }
4555                return res;
4556            } finally {
4557                Binder.restoreCallingIdentity(origId);
4558            }
4559        }
4560    }
4561
4562    @Override
4563    public void finishVoiceTask(IVoiceInteractionSession session) {
4564        synchronized(this) {
4565            final long origId = Binder.clearCallingIdentity();
4566            try {
4567                mStackSupervisor.finishVoiceTask(session);
4568            } finally {
4569                Binder.restoreCallingIdentity(origId);
4570            }
4571        }
4572
4573    }
4574
4575    @Override
4576    public boolean releaseActivityInstance(IBinder token) {
4577        synchronized(this) {
4578            final long origId = Binder.clearCallingIdentity();
4579            try {
4580                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4581                if (r.task == null || r.task.stack == null) {
4582                    return false;
4583                }
4584                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4585            } finally {
4586                Binder.restoreCallingIdentity(origId);
4587            }
4588        }
4589    }
4590
4591    @Override
4592    public void releaseSomeActivities(IApplicationThread appInt) {
4593        synchronized(this) {
4594            final long origId = Binder.clearCallingIdentity();
4595            try {
4596                ProcessRecord app = getRecordForAppLocked(appInt);
4597                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4598            } finally {
4599                Binder.restoreCallingIdentity(origId);
4600            }
4601        }
4602    }
4603
4604    @Override
4605    public boolean willActivityBeVisible(IBinder token) {
4606        synchronized(this) {
4607            ActivityStack stack = ActivityRecord.getStackLocked(token);
4608            if (stack != null) {
4609                return stack.willActivityBeVisibleLocked(token);
4610            }
4611            return false;
4612        }
4613    }
4614
4615    @Override
4616    public void overridePendingTransition(IBinder token, String packageName,
4617            int enterAnim, int exitAnim) {
4618        synchronized(this) {
4619            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4620            if (self == null) {
4621                return;
4622            }
4623
4624            final long origId = Binder.clearCallingIdentity();
4625
4626            if (self.state == ActivityState.RESUMED
4627                    || self.state == ActivityState.PAUSING) {
4628                mWindowManager.overridePendingAppTransition(packageName,
4629                        enterAnim, exitAnim, null);
4630            }
4631
4632            Binder.restoreCallingIdentity(origId);
4633        }
4634    }
4635
4636    /**
4637     * Main function for removing an existing process from the activity manager
4638     * as a result of that process going away.  Clears out all connections
4639     * to the process.
4640     */
4641    private final void handleAppDiedLocked(ProcessRecord app,
4642            boolean restarting, boolean allowRestart) {
4643        int pid = app.pid;
4644        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4645        if (!restarting) {
4646            removeLruProcessLocked(app);
4647            if (pid > 0) {
4648                ProcessList.remove(pid);
4649            }
4650        }
4651
4652        if (mProfileProc == app) {
4653            clearProfilerLocked();
4654        }
4655
4656        // Remove this application's activities from active lists.
4657        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4658
4659        app.activities.clear();
4660
4661        if (app.instrumentationClass != null) {
4662            Slog.w(TAG, "Crash of app " + app.processName
4663                  + " running instrumentation " + app.instrumentationClass);
4664            Bundle info = new Bundle();
4665            info.putString("shortMsg", "Process crashed.");
4666            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4667        }
4668
4669        if (!restarting) {
4670            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4671                // If there was nothing to resume, and we are not already
4672                // restarting this process, but there is a visible activity that
4673                // is hosted by the process...  then make sure all visible
4674                // activities are running, taking care of restarting this
4675                // process.
4676                if (hasVisibleActivities) {
4677                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4678                }
4679            }
4680        }
4681    }
4682
4683    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4684        IBinder threadBinder = thread.asBinder();
4685        // Find the application record.
4686        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4687            ProcessRecord rec = mLruProcesses.get(i);
4688            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4689                return i;
4690            }
4691        }
4692        return -1;
4693    }
4694
4695    final ProcessRecord getRecordForAppLocked(
4696            IApplicationThread thread) {
4697        if (thread == null) {
4698            return null;
4699        }
4700
4701        int appIndex = getLRURecordIndexForAppLocked(thread);
4702        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4703    }
4704
4705    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4706        // If there are no longer any background processes running,
4707        // and the app that died was not running instrumentation,
4708        // then tell everyone we are now low on memory.
4709        boolean haveBg = false;
4710        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4711            ProcessRecord rec = mLruProcesses.get(i);
4712            if (rec.thread != null
4713                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4714                haveBg = true;
4715                break;
4716            }
4717        }
4718
4719        if (!haveBg) {
4720            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4721            if (doReport) {
4722                long now = SystemClock.uptimeMillis();
4723                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4724                    doReport = false;
4725                } else {
4726                    mLastMemUsageReportTime = now;
4727                }
4728            }
4729            final ArrayList<ProcessMemInfo> memInfos
4730                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4731            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4732            long now = SystemClock.uptimeMillis();
4733            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4734                ProcessRecord rec = mLruProcesses.get(i);
4735                if (rec == dyingProc || rec.thread == null) {
4736                    continue;
4737                }
4738                if (doReport) {
4739                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4740                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4741                }
4742                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4743                    // The low memory report is overriding any current
4744                    // state for a GC request.  Make sure to do
4745                    // heavy/important/visible/foreground processes first.
4746                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4747                        rec.lastRequestedGc = 0;
4748                    } else {
4749                        rec.lastRequestedGc = rec.lastLowMemory;
4750                    }
4751                    rec.reportLowMemory = true;
4752                    rec.lastLowMemory = now;
4753                    mProcessesToGc.remove(rec);
4754                    addProcessToGcListLocked(rec);
4755                }
4756            }
4757            if (doReport) {
4758                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4759                mHandler.sendMessage(msg);
4760            }
4761            scheduleAppGcsLocked();
4762        }
4763    }
4764
4765    final void appDiedLocked(ProcessRecord app) {
4766       appDiedLocked(app, app.pid, app.thread);
4767    }
4768
4769    final void appDiedLocked(ProcessRecord app, int pid,
4770            IApplicationThread thread) {
4771
4772        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4773        synchronized (stats) {
4774            stats.noteProcessDiedLocked(app.info.uid, pid);
4775        }
4776
4777        Process.killProcessGroup(app.info.uid, pid);
4778
4779        // Clean up already done if the process has been re-started.
4780        if (app.pid == pid && app.thread != null &&
4781                app.thread.asBinder() == thread.asBinder()) {
4782            boolean doLowMem = app.instrumentationClass == null;
4783            boolean doOomAdj = doLowMem;
4784            if (!app.killedByAm) {
4785                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4786                        + ") has died.");
4787                mAllowLowerMemLevel = true;
4788            } else {
4789                // Note that we always want to do oom adj to update our state with the
4790                // new number of procs.
4791                mAllowLowerMemLevel = false;
4792                doLowMem = false;
4793            }
4794            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4795            if (DEBUG_CLEANUP) Slog.v(
4796                TAG, "Dying app: " + app + ", pid: " + pid
4797                + ", thread: " + thread.asBinder());
4798            handleAppDiedLocked(app, false, true);
4799
4800            if (doOomAdj) {
4801                updateOomAdjLocked();
4802            }
4803            if (doLowMem) {
4804                doLowMemReportIfNeededLocked(app);
4805            }
4806        } else if (app.pid != pid) {
4807            // A new process has already been started.
4808            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4809                    + ") has died and restarted (pid " + app.pid + ").");
4810            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4811        } else if (DEBUG_PROCESSES) {
4812            Slog.d(TAG, "Received spurious death notification for thread "
4813                    + thread.asBinder());
4814        }
4815    }
4816
4817    /**
4818     * If a stack trace dump file is configured, dump process stack traces.
4819     * @param clearTraces causes the dump file to be erased prior to the new
4820     *    traces being written, if true; when false, the new traces will be
4821     *    appended to any existing file content.
4822     * @param firstPids of dalvik VM processes to dump stack traces for first
4823     * @param lastPids of dalvik VM processes to dump stack traces for last
4824     * @param nativeProcs optional list of native process names to dump stack crawls
4825     * @return file containing stack traces, or null if no dump file is configured
4826     */
4827    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4828            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4829        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4830        if (tracesPath == null || tracesPath.length() == 0) {
4831            return null;
4832        }
4833
4834        File tracesFile = new File(tracesPath);
4835        try {
4836            File tracesDir = tracesFile.getParentFile();
4837            if (!tracesDir.exists()) {
4838                tracesFile.mkdirs();
4839                if (!SELinux.restorecon(tracesDir)) {
4840                    return null;
4841                }
4842            }
4843            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4844
4845            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4846            tracesFile.createNewFile();
4847            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4848        } catch (IOException e) {
4849            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4850            return null;
4851        }
4852
4853        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4854        return tracesFile;
4855    }
4856
4857    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4858            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4859        // Use a FileObserver to detect when traces finish writing.
4860        // The order of traces is considered important to maintain for legibility.
4861        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4862            @Override
4863            public synchronized void onEvent(int event, String path) { notify(); }
4864        };
4865
4866        try {
4867            observer.startWatching();
4868
4869            // First collect all of the stacks of the most important pids.
4870            if (firstPids != null) {
4871                try {
4872                    int num = firstPids.size();
4873                    for (int i = 0; i < num; i++) {
4874                        synchronized (observer) {
4875                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4876                            observer.wait(200);  // Wait for write-close, give up after 200msec
4877                        }
4878                    }
4879                } catch (InterruptedException e) {
4880                    Log.wtf(TAG, e);
4881                }
4882            }
4883
4884            // Next collect the stacks of the native pids
4885            if (nativeProcs != null) {
4886                int[] pids = Process.getPidsForCommands(nativeProcs);
4887                if (pids != null) {
4888                    for (int pid : pids) {
4889                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4890                    }
4891                }
4892            }
4893
4894            // Lastly, measure CPU usage.
4895            if (processCpuTracker != null) {
4896                processCpuTracker.init();
4897                System.gc();
4898                processCpuTracker.update();
4899                try {
4900                    synchronized (processCpuTracker) {
4901                        processCpuTracker.wait(500); // measure over 1/2 second.
4902                    }
4903                } catch (InterruptedException e) {
4904                }
4905                processCpuTracker.update();
4906
4907                // We'll take the stack crawls of just the top apps using CPU.
4908                final int N = processCpuTracker.countWorkingStats();
4909                int numProcs = 0;
4910                for (int i=0; i<N && numProcs<5; i++) {
4911                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4912                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4913                        numProcs++;
4914                        try {
4915                            synchronized (observer) {
4916                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4917                                observer.wait(200);  // Wait for write-close, give up after 200msec
4918                            }
4919                        } catch (InterruptedException e) {
4920                            Log.wtf(TAG, e);
4921                        }
4922
4923                    }
4924                }
4925            }
4926        } finally {
4927            observer.stopWatching();
4928        }
4929    }
4930
4931    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4932        if (true || IS_USER_BUILD) {
4933            return;
4934        }
4935        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4936        if (tracesPath == null || tracesPath.length() == 0) {
4937            return;
4938        }
4939
4940        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4941        StrictMode.allowThreadDiskWrites();
4942        try {
4943            final File tracesFile = new File(tracesPath);
4944            final File tracesDir = tracesFile.getParentFile();
4945            final File tracesTmp = new File(tracesDir, "__tmp__");
4946            try {
4947                if (!tracesDir.exists()) {
4948                    tracesFile.mkdirs();
4949                    if (!SELinux.restorecon(tracesDir.getPath())) {
4950                        return;
4951                    }
4952                }
4953                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4954
4955                if (tracesFile.exists()) {
4956                    tracesTmp.delete();
4957                    tracesFile.renameTo(tracesTmp);
4958                }
4959                StringBuilder sb = new StringBuilder();
4960                Time tobj = new Time();
4961                tobj.set(System.currentTimeMillis());
4962                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4963                sb.append(": ");
4964                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4965                sb.append(" since ");
4966                sb.append(msg);
4967                FileOutputStream fos = new FileOutputStream(tracesFile);
4968                fos.write(sb.toString().getBytes());
4969                if (app == null) {
4970                    fos.write("\n*** No application process!".getBytes());
4971                }
4972                fos.close();
4973                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4974            } catch (IOException e) {
4975                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4976                return;
4977            }
4978
4979            if (app != null) {
4980                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4981                firstPids.add(app.pid);
4982                dumpStackTraces(tracesPath, firstPids, null, null, null);
4983            }
4984
4985            File lastTracesFile = null;
4986            File curTracesFile = null;
4987            for (int i=9; i>=0; i--) {
4988                String name = String.format(Locale.US, "slow%02d.txt", i);
4989                curTracesFile = new File(tracesDir, name);
4990                if (curTracesFile.exists()) {
4991                    if (lastTracesFile != null) {
4992                        curTracesFile.renameTo(lastTracesFile);
4993                    } else {
4994                        curTracesFile.delete();
4995                    }
4996                }
4997                lastTracesFile = curTracesFile;
4998            }
4999            tracesFile.renameTo(curTracesFile);
5000            if (tracesTmp.exists()) {
5001                tracesTmp.renameTo(tracesFile);
5002            }
5003        } finally {
5004            StrictMode.setThreadPolicy(oldPolicy);
5005        }
5006    }
5007
5008    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5009            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5010        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5011        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5012
5013        if (mController != null) {
5014            try {
5015                // 0 == continue, -1 = kill process immediately
5016                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5017                if (res < 0 && app.pid != MY_PID) {
5018                    app.kill("anr", true);
5019                }
5020            } catch (RemoteException e) {
5021                mController = null;
5022                Watchdog.getInstance().setActivityController(null);
5023            }
5024        }
5025
5026        long anrTime = SystemClock.uptimeMillis();
5027        if (MONITOR_CPU_USAGE) {
5028            updateCpuStatsNow();
5029        }
5030
5031        synchronized (this) {
5032            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5033            if (mShuttingDown) {
5034                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5035                return;
5036            } else if (app.notResponding) {
5037                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5038                return;
5039            } else if (app.crashing) {
5040                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5041                return;
5042            }
5043
5044            // In case we come through here for the same app before completing
5045            // this one, mark as anring now so we will bail out.
5046            app.notResponding = true;
5047
5048            // Log the ANR to the event log.
5049            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5050                    app.processName, app.info.flags, annotation);
5051
5052            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5053            firstPids.add(app.pid);
5054
5055            int parentPid = app.pid;
5056            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5057            if (parentPid != app.pid) firstPids.add(parentPid);
5058
5059            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5060
5061            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5062                ProcessRecord r = mLruProcesses.get(i);
5063                if (r != null && r.thread != null) {
5064                    int pid = r.pid;
5065                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5066                        if (r.persistent) {
5067                            firstPids.add(pid);
5068                        } else {
5069                            lastPids.put(pid, Boolean.TRUE);
5070                        }
5071                    }
5072                }
5073            }
5074        }
5075
5076        // Log the ANR to the main log.
5077        StringBuilder info = new StringBuilder();
5078        info.setLength(0);
5079        info.append("ANR in ").append(app.processName);
5080        if (activity != null && activity.shortComponentName != null) {
5081            info.append(" (").append(activity.shortComponentName).append(")");
5082        }
5083        info.append("\n");
5084        info.append("PID: ").append(app.pid).append("\n");
5085        if (annotation != null) {
5086            info.append("Reason: ").append(annotation).append("\n");
5087        }
5088        if (parent != null && parent != activity) {
5089            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5090        }
5091
5092        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5093
5094        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5095                NATIVE_STACKS_OF_INTEREST);
5096
5097        String cpuInfo = null;
5098        if (MONITOR_CPU_USAGE) {
5099            updateCpuStatsNow();
5100            synchronized (mProcessCpuTracker) {
5101                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5102            }
5103            info.append(processCpuTracker.printCurrentLoad());
5104            info.append(cpuInfo);
5105        }
5106
5107        info.append(processCpuTracker.printCurrentState(anrTime));
5108
5109        Slog.e(TAG, info.toString());
5110        if (tracesFile == null) {
5111            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5112            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5113        }
5114
5115        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5116                cpuInfo, tracesFile, null);
5117
5118        if (mController != null) {
5119            try {
5120                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5121                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5122                if (res != 0) {
5123                    if (res < 0 && app.pid != MY_PID) {
5124                        app.kill("anr", true);
5125                    } else {
5126                        synchronized (this) {
5127                            mServices.scheduleServiceTimeoutLocked(app);
5128                        }
5129                    }
5130                    return;
5131                }
5132            } catch (RemoteException e) {
5133                mController = null;
5134                Watchdog.getInstance().setActivityController(null);
5135            }
5136        }
5137
5138        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5139        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5140                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5141
5142        synchronized (this) {
5143            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5144                app.kill("bg anr", true);
5145                return;
5146            }
5147
5148            // Set the app's notResponding state, and look up the errorReportReceiver
5149            makeAppNotRespondingLocked(app,
5150                    activity != null ? activity.shortComponentName : null,
5151                    annotation != null ? "ANR " + annotation : "ANR",
5152                    info.toString());
5153
5154            // Bring up the infamous App Not Responding dialog
5155            Message msg = Message.obtain();
5156            HashMap<String, Object> map = new HashMap<String, Object>();
5157            msg.what = SHOW_NOT_RESPONDING_MSG;
5158            msg.obj = map;
5159            msg.arg1 = aboveSystem ? 1 : 0;
5160            map.put("app", app);
5161            if (activity != null) {
5162                map.put("activity", activity);
5163            }
5164
5165            mHandler.sendMessage(msg);
5166        }
5167    }
5168
5169    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5170        if (!mLaunchWarningShown) {
5171            mLaunchWarningShown = true;
5172            mHandler.post(new Runnable() {
5173                @Override
5174                public void run() {
5175                    synchronized (ActivityManagerService.this) {
5176                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5177                        d.show();
5178                        mHandler.postDelayed(new Runnable() {
5179                            @Override
5180                            public void run() {
5181                                synchronized (ActivityManagerService.this) {
5182                                    d.dismiss();
5183                                    mLaunchWarningShown = false;
5184                                }
5185                            }
5186                        }, 4000);
5187                    }
5188                }
5189            });
5190        }
5191    }
5192
5193    @Override
5194    public boolean clearApplicationUserData(final String packageName,
5195            final IPackageDataObserver observer, int userId) {
5196        enforceNotIsolatedCaller("clearApplicationUserData");
5197        int uid = Binder.getCallingUid();
5198        int pid = Binder.getCallingPid();
5199        userId = handleIncomingUser(pid, uid,
5200                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5201        long callingId = Binder.clearCallingIdentity();
5202        try {
5203            IPackageManager pm = AppGlobals.getPackageManager();
5204            int pkgUid = -1;
5205            synchronized(this) {
5206                try {
5207                    pkgUid = pm.getPackageUid(packageName, userId);
5208                } catch (RemoteException e) {
5209                }
5210                if (pkgUid == -1) {
5211                    Slog.w(TAG, "Invalid packageName: " + packageName);
5212                    if (observer != null) {
5213                        try {
5214                            observer.onRemoveCompleted(packageName, false);
5215                        } catch (RemoteException e) {
5216                            Slog.i(TAG, "Observer no longer exists.");
5217                        }
5218                    }
5219                    return false;
5220                }
5221                if (uid == pkgUid || checkComponentPermission(
5222                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5223                        pid, uid, -1, true)
5224                        == PackageManager.PERMISSION_GRANTED) {
5225                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5226                } else {
5227                    throw new SecurityException("PID " + pid + " does not have permission "
5228                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5229                                    + " of package " + packageName);
5230                }
5231
5232                // Remove all tasks match the cleared application package and user
5233                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5234                    final TaskRecord tr = mRecentTasks.get(i);
5235                    final String taskPackageName =
5236                            tr.getBaseIntent().getComponent().getPackageName();
5237                    if (tr.userId != userId) continue;
5238                    if (!taskPackageName.equals(packageName)) continue;
5239                    removeTaskByIdLocked(tr.taskId, 0);
5240                }
5241            }
5242
5243            try {
5244                // Clear application user data
5245                pm.clearApplicationUserData(packageName, observer, userId);
5246
5247                synchronized(this) {
5248                    // Remove all permissions granted from/to this package
5249                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5250                }
5251
5252                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5253                        Uri.fromParts("package", packageName, null));
5254                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5255                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5256                        null, null, 0, null, null, null, false, false, userId);
5257            } catch (RemoteException e) {
5258            }
5259        } finally {
5260            Binder.restoreCallingIdentity(callingId);
5261        }
5262        return true;
5263    }
5264
5265    @Override
5266    public void killBackgroundProcesses(final String packageName, int userId) {
5267        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5268                != PackageManager.PERMISSION_GRANTED &&
5269                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5270                        != PackageManager.PERMISSION_GRANTED) {
5271            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5272                    + Binder.getCallingPid()
5273                    + ", uid=" + Binder.getCallingUid()
5274                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5275            Slog.w(TAG, msg);
5276            throw new SecurityException(msg);
5277        }
5278
5279        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5280                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5281        long callingId = Binder.clearCallingIdentity();
5282        try {
5283            IPackageManager pm = AppGlobals.getPackageManager();
5284            synchronized(this) {
5285                int appId = -1;
5286                try {
5287                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5288                } catch (RemoteException e) {
5289                }
5290                if (appId == -1) {
5291                    Slog.w(TAG, "Invalid packageName: " + packageName);
5292                    return;
5293                }
5294                killPackageProcessesLocked(packageName, appId, userId,
5295                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5296            }
5297        } finally {
5298            Binder.restoreCallingIdentity(callingId);
5299        }
5300    }
5301
5302    @Override
5303    public void killAllBackgroundProcesses() {
5304        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5305                != PackageManager.PERMISSION_GRANTED) {
5306            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5307                    + Binder.getCallingPid()
5308                    + ", uid=" + Binder.getCallingUid()
5309                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5310            Slog.w(TAG, msg);
5311            throw new SecurityException(msg);
5312        }
5313
5314        long callingId = Binder.clearCallingIdentity();
5315        try {
5316            synchronized(this) {
5317                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5318                final int NP = mProcessNames.getMap().size();
5319                for (int ip=0; ip<NP; ip++) {
5320                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5321                    final int NA = apps.size();
5322                    for (int ia=0; ia<NA; ia++) {
5323                        ProcessRecord app = apps.valueAt(ia);
5324                        if (app.persistent) {
5325                            // we don't kill persistent processes
5326                            continue;
5327                        }
5328                        if (app.removed) {
5329                            procs.add(app);
5330                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5331                            app.removed = true;
5332                            procs.add(app);
5333                        }
5334                    }
5335                }
5336
5337                int N = procs.size();
5338                for (int i=0; i<N; i++) {
5339                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5340                }
5341                mAllowLowerMemLevel = true;
5342                updateOomAdjLocked();
5343                doLowMemReportIfNeededLocked(null);
5344            }
5345        } finally {
5346            Binder.restoreCallingIdentity(callingId);
5347        }
5348    }
5349
5350    @Override
5351    public void forceStopPackage(final String packageName, int userId) {
5352        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5353                != PackageManager.PERMISSION_GRANTED) {
5354            String msg = "Permission Denial: forceStopPackage() from pid="
5355                    + Binder.getCallingPid()
5356                    + ", uid=" + Binder.getCallingUid()
5357                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5358            Slog.w(TAG, msg);
5359            throw new SecurityException(msg);
5360        }
5361        final int callingPid = Binder.getCallingPid();
5362        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5363                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5364        long callingId = Binder.clearCallingIdentity();
5365        try {
5366            IPackageManager pm = AppGlobals.getPackageManager();
5367            synchronized(this) {
5368                int[] users = userId == UserHandle.USER_ALL
5369                        ? getUsersLocked() : new int[] { userId };
5370                for (int user : users) {
5371                    int pkgUid = -1;
5372                    try {
5373                        pkgUid = pm.getPackageUid(packageName, user);
5374                    } catch (RemoteException e) {
5375                    }
5376                    if (pkgUid == -1) {
5377                        Slog.w(TAG, "Invalid packageName: " + packageName);
5378                        continue;
5379                    }
5380                    try {
5381                        pm.setPackageStoppedState(packageName, true, user);
5382                    } catch (RemoteException e) {
5383                    } catch (IllegalArgumentException e) {
5384                        Slog.w(TAG, "Failed trying to unstop package "
5385                                + packageName + ": " + e);
5386                    }
5387                    if (isUserRunningLocked(user, false)) {
5388                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5389                    }
5390                }
5391            }
5392        } finally {
5393            Binder.restoreCallingIdentity(callingId);
5394        }
5395    }
5396
5397    @Override
5398    public void addPackageDependency(String packageName) {
5399        synchronized (this) {
5400            int callingPid = Binder.getCallingPid();
5401            if (callingPid == Process.myPid()) {
5402                //  Yeah, um, no.
5403                Slog.w(TAG, "Can't addPackageDependency on system process");
5404                return;
5405            }
5406            ProcessRecord proc;
5407            synchronized (mPidsSelfLocked) {
5408                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5409            }
5410            if (proc != null) {
5411                if (proc.pkgDeps == null) {
5412                    proc.pkgDeps = new ArraySet<String>(1);
5413                }
5414                proc.pkgDeps.add(packageName);
5415            }
5416        }
5417    }
5418
5419    /*
5420     * The pkg name and app id have to be specified.
5421     */
5422    @Override
5423    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5424        if (pkg == null) {
5425            return;
5426        }
5427        // Make sure the uid is valid.
5428        if (appid < 0) {
5429            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5430            return;
5431        }
5432        int callerUid = Binder.getCallingUid();
5433        // Only the system server can kill an application
5434        if (callerUid == Process.SYSTEM_UID) {
5435            // Post an aysnc message to kill the application
5436            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5437            msg.arg1 = appid;
5438            msg.arg2 = 0;
5439            Bundle bundle = new Bundle();
5440            bundle.putString("pkg", pkg);
5441            bundle.putString("reason", reason);
5442            msg.obj = bundle;
5443            mHandler.sendMessage(msg);
5444        } else {
5445            throw new SecurityException(callerUid + " cannot kill pkg: " +
5446                    pkg);
5447        }
5448    }
5449
5450    @Override
5451    public void closeSystemDialogs(String reason) {
5452        enforceNotIsolatedCaller("closeSystemDialogs");
5453
5454        final int pid = Binder.getCallingPid();
5455        final int uid = Binder.getCallingUid();
5456        final long origId = Binder.clearCallingIdentity();
5457        try {
5458            synchronized (this) {
5459                // Only allow this from foreground processes, so that background
5460                // applications can't abuse it to prevent system UI from being shown.
5461                if (uid >= Process.FIRST_APPLICATION_UID) {
5462                    ProcessRecord proc;
5463                    synchronized (mPidsSelfLocked) {
5464                        proc = mPidsSelfLocked.get(pid);
5465                    }
5466                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5467                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5468                                + " from background process " + proc);
5469                        return;
5470                    }
5471                }
5472                closeSystemDialogsLocked(reason);
5473            }
5474        } finally {
5475            Binder.restoreCallingIdentity(origId);
5476        }
5477    }
5478
5479    void closeSystemDialogsLocked(String reason) {
5480        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5481        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5482                | Intent.FLAG_RECEIVER_FOREGROUND);
5483        if (reason != null) {
5484            intent.putExtra("reason", reason);
5485        }
5486        mWindowManager.closeSystemDialogs(reason);
5487
5488        mStackSupervisor.closeSystemDialogsLocked();
5489
5490        broadcastIntentLocked(null, null, intent, null,
5491                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5492                Process.SYSTEM_UID, UserHandle.USER_ALL);
5493    }
5494
5495    @Override
5496    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5497        enforceNotIsolatedCaller("getProcessMemoryInfo");
5498        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5499        for (int i=pids.length-1; i>=0; i--) {
5500            ProcessRecord proc;
5501            int oomAdj;
5502            synchronized (this) {
5503                synchronized (mPidsSelfLocked) {
5504                    proc = mPidsSelfLocked.get(pids[i]);
5505                    oomAdj = proc != null ? proc.setAdj : 0;
5506                }
5507            }
5508            infos[i] = new Debug.MemoryInfo();
5509            Debug.getMemoryInfo(pids[i], infos[i]);
5510            if (proc != null) {
5511                synchronized (this) {
5512                    if (proc.thread != null && proc.setAdj == oomAdj) {
5513                        // Record this for posterity if the process has been stable.
5514                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5515                                infos[i].getTotalUss(), false, proc.pkgList);
5516                    }
5517                }
5518            }
5519        }
5520        return infos;
5521    }
5522
5523    @Override
5524    public long[] getProcessPss(int[] pids) {
5525        enforceNotIsolatedCaller("getProcessPss");
5526        long[] pss = new long[pids.length];
5527        for (int i=pids.length-1; i>=0; i--) {
5528            ProcessRecord proc;
5529            int oomAdj;
5530            synchronized (this) {
5531                synchronized (mPidsSelfLocked) {
5532                    proc = mPidsSelfLocked.get(pids[i]);
5533                    oomAdj = proc != null ? proc.setAdj : 0;
5534                }
5535            }
5536            long[] tmpUss = new long[1];
5537            pss[i] = Debug.getPss(pids[i], tmpUss);
5538            if (proc != null) {
5539                synchronized (this) {
5540                    if (proc.thread != null && proc.setAdj == oomAdj) {
5541                        // Record this for posterity if the process has been stable.
5542                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5543                    }
5544                }
5545            }
5546        }
5547        return pss;
5548    }
5549
5550    @Override
5551    public void killApplicationProcess(String processName, int uid) {
5552        if (processName == null) {
5553            return;
5554        }
5555
5556        int callerUid = Binder.getCallingUid();
5557        // Only the system server can kill an application
5558        if (callerUid == Process.SYSTEM_UID) {
5559            synchronized (this) {
5560                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5561                if (app != null && app.thread != null) {
5562                    try {
5563                        app.thread.scheduleSuicide();
5564                    } catch (RemoteException e) {
5565                        // If the other end already died, then our work here is done.
5566                    }
5567                } else {
5568                    Slog.w(TAG, "Process/uid not found attempting kill of "
5569                            + processName + " / " + uid);
5570                }
5571            }
5572        } else {
5573            throw new SecurityException(callerUid + " cannot kill app process: " +
5574                    processName);
5575        }
5576    }
5577
5578    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5579        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5580                false, true, false, false, UserHandle.getUserId(uid), reason);
5581        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5582                Uri.fromParts("package", packageName, null));
5583        if (!mProcessesReady) {
5584            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5585                    | Intent.FLAG_RECEIVER_FOREGROUND);
5586        }
5587        intent.putExtra(Intent.EXTRA_UID, uid);
5588        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5589        broadcastIntentLocked(null, null, intent,
5590                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5591                false, false,
5592                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5593    }
5594
5595    private void forceStopUserLocked(int userId, String reason) {
5596        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5597        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5598        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5599                | Intent.FLAG_RECEIVER_FOREGROUND);
5600        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5601        broadcastIntentLocked(null, null, intent,
5602                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5603                false, false,
5604                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5605    }
5606
5607    private final boolean killPackageProcessesLocked(String packageName, int appId,
5608            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5609            boolean doit, boolean evenPersistent, String reason) {
5610        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5611
5612        // Remove all processes this package may have touched: all with the
5613        // same UID (except for the system or root user), and all whose name
5614        // matches the package name.
5615        final int NP = mProcessNames.getMap().size();
5616        for (int ip=0; ip<NP; ip++) {
5617            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5618            final int NA = apps.size();
5619            for (int ia=0; ia<NA; ia++) {
5620                ProcessRecord app = apps.valueAt(ia);
5621                if (app.persistent && !evenPersistent) {
5622                    // we don't kill persistent processes
5623                    continue;
5624                }
5625                if (app.removed) {
5626                    if (doit) {
5627                        procs.add(app);
5628                    }
5629                    continue;
5630                }
5631
5632                // Skip process if it doesn't meet our oom adj requirement.
5633                if (app.setAdj < minOomAdj) {
5634                    continue;
5635                }
5636
5637                // If no package is specified, we call all processes under the
5638                // give user id.
5639                if (packageName == null) {
5640                    if (app.userId != userId) {
5641                        continue;
5642                    }
5643                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5644                        continue;
5645                    }
5646                // Package has been specified, we want to hit all processes
5647                // that match it.  We need to qualify this by the processes
5648                // that are running under the specified app and user ID.
5649                } else {
5650                    final boolean isDep = app.pkgDeps != null
5651                            && app.pkgDeps.contains(packageName);
5652                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5653                        continue;
5654                    }
5655                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5656                        continue;
5657                    }
5658                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5659                        continue;
5660                    }
5661                }
5662
5663                // Process has passed all conditions, kill it!
5664                if (!doit) {
5665                    return true;
5666                }
5667                app.removed = true;
5668                procs.add(app);
5669            }
5670        }
5671
5672        int N = procs.size();
5673        for (int i=0; i<N; i++) {
5674            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5675        }
5676        updateOomAdjLocked();
5677        return N > 0;
5678    }
5679
5680    private final boolean forceStopPackageLocked(String name, int appId,
5681            boolean callerWillRestart, boolean purgeCache, boolean doit,
5682            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5683        int i;
5684        int N;
5685
5686        if (userId == UserHandle.USER_ALL && name == null) {
5687            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5688        }
5689
5690        if (appId < 0 && name != null) {
5691            try {
5692                appId = UserHandle.getAppId(
5693                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5694            } catch (RemoteException e) {
5695            }
5696        }
5697
5698        if (doit) {
5699            if (name != null) {
5700                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5701                        + " user=" + userId + ": " + reason);
5702            } else {
5703                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5704            }
5705
5706            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5707            for (int ip=pmap.size()-1; ip>=0; ip--) {
5708                SparseArray<Long> ba = pmap.valueAt(ip);
5709                for (i=ba.size()-1; i>=0; i--) {
5710                    boolean remove = false;
5711                    final int entUid = ba.keyAt(i);
5712                    if (name != null) {
5713                        if (userId == UserHandle.USER_ALL) {
5714                            if (UserHandle.getAppId(entUid) == appId) {
5715                                remove = true;
5716                            }
5717                        } else {
5718                            if (entUid == UserHandle.getUid(userId, appId)) {
5719                                remove = true;
5720                            }
5721                        }
5722                    } else if (UserHandle.getUserId(entUid) == userId) {
5723                        remove = true;
5724                    }
5725                    if (remove) {
5726                        ba.removeAt(i);
5727                    }
5728                }
5729                if (ba.size() == 0) {
5730                    pmap.removeAt(ip);
5731                }
5732            }
5733        }
5734
5735        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5736                -100, callerWillRestart, true, doit, evenPersistent,
5737                name == null ? ("stop user " + userId) : ("stop " + name));
5738
5739        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5740            if (!doit) {
5741                return true;
5742            }
5743            didSomething = true;
5744        }
5745
5746        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5747            if (!doit) {
5748                return true;
5749            }
5750            didSomething = true;
5751        }
5752
5753        if (name == null) {
5754            // Remove all sticky broadcasts from this user.
5755            mStickyBroadcasts.remove(userId);
5756        }
5757
5758        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5759        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5760                userId, providers)) {
5761            if (!doit) {
5762                return true;
5763            }
5764            didSomething = true;
5765        }
5766        N = providers.size();
5767        for (i=0; i<N; i++) {
5768            removeDyingProviderLocked(null, providers.get(i), true);
5769        }
5770
5771        // Remove transient permissions granted from/to this package/user
5772        removeUriPermissionsForPackageLocked(name, userId, false);
5773
5774        if (name == null || uninstalling) {
5775            // Remove pending intents.  For now we only do this when force
5776            // stopping users, because we have some problems when doing this
5777            // for packages -- app widgets are not currently cleaned up for
5778            // such packages, so they can be left with bad pending intents.
5779            if (mIntentSenderRecords.size() > 0) {
5780                Iterator<WeakReference<PendingIntentRecord>> it
5781                        = mIntentSenderRecords.values().iterator();
5782                while (it.hasNext()) {
5783                    WeakReference<PendingIntentRecord> wpir = it.next();
5784                    if (wpir == null) {
5785                        it.remove();
5786                        continue;
5787                    }
5788                    PendingIntentRecord pir = wpir.get();
5789                    if (pir == null) {
5790                        it.remove();
5791                        continue;
5792                    }
5793                    if (name == null) {
5794                        // Stopping user, remove all objects for the user.
5795                        if (pir.key.userId != userId) {
5796                            // Not the same user, skip it.
5797                            continue;
5798                        }
5799                    } else {
5800                        if (UserHandle.getAppId(pir.uid) != appId) {
5801                            // Different app id, skip it.
5802                            continue;
5803                        }
5804                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5805                            // Different user, skip it.
5806                            continue;
5807                        }
5808                        if (!pir.key.packageName.equals(name)) {
5809                            // Different package, skip it.
5810                            continue;
5811                        }
5812                    }
5813                    if (!doit) {
5814                        return true;
5815                    }
5816                    didSomething = true;
5817                    it.remove();
5818                    pir.canceled = true;
5819                    if (pir.key.activity != null) {
5820                        pir.key.activity.pendingResults.remove(pir.ref);
5821                    }
5822                }
5823            }
5824        }
5825
5826        if (doit) {
5827            if (purgeCache && name != null) {
5828                AttributeCache ac = AttributeCache.instance();
5829                if (ac != null) {
5830                    ac.removePackage(name);
5831                }
5832            }
5833            if (mBooted) {
5834                mStackSupervisor.resumeTopActivitiesLocked();
5835                mStackSupervisor.scheduleIdleLocked();
5836            }
5837        }
5838
5839        return didSomething;
5840    }
5841
5842    private final boolean removeProcessLocked(ProcessRecord app,
5843            boolean callerWillRestart, boolean allowRestart, String reason) {
5844        final String name = app.processName;
5845        final int uid = app.uid;
5846        if (DEBUG_PROCESSES) Slog.d(
5847            TAG, "Force removing proc " + app.toShortString() + " (" + name
5848            + "/" + uid + ")");
5849
5850        mProcessNames.remove(name, uid);
5851        mIsolatedProcesses.remove(app.uid);
5852        if (mHeavyWeightProcess == app) {
5853            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5854                    mHeavyWeightProcess.userId, 0));
5855            mHeavyWeightProcess = null;
5856        }
5857        boolean needRestart = false;
5858        if (app.pid > 0 && app.pid != MY_PID) {
5859            int pid = app.pid;
5860            synchronized (mPidsSelfLocked) {
5861                mPidsSelfLocked.remove(pid);
5862                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5863            }
5864            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5865            if (app.isolated) {
5866                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5867            }
5868            app.kill(reason, true);
5869            handleAppDiedLocked(app, true, allowRestart);
5870            removeLruProcessLocked(app);
5871
5872            if (app.persistent && !app.isolated) {
5873                if (!callerWillRestart) {
5874                    addAppLocked(app.info, false, null /* ABI override */);
5875                } else {
5876                    needRestart = true;
5877                }
5878            }
5879        } else {
5880            mRemovedProcesses.add(app);
5881        }
5882
5883        return needRestart;
5884    }
5885
5886    private final void processStartTimedOutLocked(ProcessRecord app) {
5887        final int pid = app.pid;
5888        boolean gone = false;
5889        synchronized (mPidsSelfLocked) {
5890            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5891            if (knownApp != null && knownApp.thread == null) {
5892                mPidsSelfLocked.remove(pid);
5893                gone = true;
5894            }
5895        }
5896
5897        if (gone) {
5898            Slog.w(TAG, "Process " + app + " failed to attach");
5899            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5900                    pid, app.uid, app.processName);
5901            mProcessNames.remove(app.processName, app.uid);
5902            mIsolatedProcesses.remove(app.uid);
5903            if (mHeavyWeightProcess == app) {
5904                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5905                        mHeavyWeightProcess.userId, 0));
5906                mHeavyWeightProcess = null;
5907            }
5908            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5909            if (app.isolated) {
5910                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5911            }
5912            // Take care of any launching providers waiting for this process.
5913            checkAppInLaunchingProvidersLocked(app, true);
5914            // Take care of any services that are waiting for the process.
5915            mServices.processStartTimedOutLocked(app);
5916            app.kill("start timeout", true);
5917            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5918                Slog.w(TAG, "Unattached app died before backup, skipping");
5919                try {
5920                    IBackupManager bm = IBackupManager.Stub.asInterface(
5921                            ServiceManager.getService(Context.BACKUP_SERVICE));
5922                    bm.agentDisconnected(app.info.packageName);
5923                } catch (RemoteException e) {
5924                    // Can't happen; the backup manager is local
5925                }
5926            }
5927            if (isPendingBroadcastProcessLocked(pid)) {
5928                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5929                skipPendingBroadcastLocked(pid);
5930            }
5931        } else {
5932            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5933        }
5934    }
5935
5936    private final boolean attachApplicationLocked(IApplicationThread thread,
5937            int pid) {
5938
5939        // Find the application record that is being attached...  either via
5940        // the pid if we are running in multiple processes, or just pull the
5941        // next app record if we are emulating process with anonymous threads.
5942        ProcessRecord app;
5943        if (pid != MY_PID && pid >= 0) {
5944            synchronized (mPidsSelfLocked) {
5945                app = mPidsSelfLocked.get(pid);
5946            }
5947        } else {
5948            app = null;
5949        }
5950
5951        if (app == null) {
5952            Slog.w(TAG, "No pending application record for pid " + pid
5953                    + " (IApplicationThread " + thread + "); dropping process");
5954            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5955            if (pid > 0 && pid != MY_PID) {
5956                Process.killProcessQuiet(pid);
5957                //TODO: Process.killProcessGroup(app.info.uid, pid);
5958            } else {
5959                try {
5960                    thread.scheduleExit();
5961                } catch (Exception e) {
5962                    // Ignore exceptions.
5963                }
5964            }
5965            return false;
5966        }
5967
5968        // If this application record is still attached to a previous
5969        // process, clean it up now.
5970        if (app.thread != null) {
5971            handleAppDiedLocked(app, true, true);
5972        }
5973
5974        // Tell the process all about itself.
5975
5976        if (localLOGV) Slog.v(
5977                TAG, "Binding process pid " + pid + " to record " + app);
5978
5979        final String processName = app.processName;
5980        try {
5981            AppDeathRecipient adr = new AppDeathRecipient(
5982                    app, pid, thread);
5983            thread.asBinder().linkToDeath(adr, 0);
5984            app.deathRecipient = adr;
5985        } catch (RemoteException e) {
5986            app.resetPackageList(mProcessStats);
5987            startProcessLocked(app, "link fail", processName);
5988            return false;
5989        }
5990
5991        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5992
5993        app.makeActive(thread, mProcessStats);
5994        app.curAdj = app.setAdj = -100;
5995        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5996        app.forcingToForeground = null;
5997        updateProcessForegroundLocked(app, false, false);
5998        app.hasShownUi = false;
5999        app.debugging = false;
6000        app.cached = false;
6001
6002        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6003
6004        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6005        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6006
6007        if (!normalMode) {
6008            Slog.i(TAG, "Launching preboot mode app: " + app);
6009        }
6010
6011        if (localLOGV) Slog.v(
6012            TAG, "New app record " + app
6013            + " thread=" + thread.asBinder() + " pid=" + pid);
6014        try {
6015            int testMode = IApplicationThread.DEBUG_OFF;
6016            if (mDebugApp != null && mDebugApp.equals(processName)) {
6017                testMode = mWaitForDebugger
6018                    ? IApplicationThread.DEBUG_WAIT
6019                    : IApplicationThread.DEBUG_ON;
6020                app.debugging = true;
6021                if (mDebugTransient) {
6022                    mDebugApp = mOrigDebugApp;
6023                    mWaitForDebugger = mOrigWaitForDebugger;
6024                }
6025            }
6026            String profileFile = app.instrumentationProfileFile;
6027            ParcelFileDescriptor profileFd = null;
6028            int samplingInterval = 0;
6029            boolean profileAutoStop = false;
6030            if (mProfileApp != null && mProfileApp.equals(processName)) {
6031                mProfileProc = app;
6032                profileFile = mProfileFile;
6033                profileFd = mProfileFd;
6034                samplingInterval = mSamplingInterval;
6035                profileAutoStop = mAutoStopProfiler;
6036            }
6037            boolean enableOpenGlTrace = false;
6038            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6039                enableOpenGlTrace = true;
6040                mOpenGlTraceApp = null;
6041            }
6042
6043            // If the app is being launched for restore or full backup, set it up specially
6044            boolean isRestrictedBackupMode = false;
6045            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6046                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6047                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6048                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6049            }
6050
6051            ensurePackageDexOpt(app.instrumentationInfo != null
6052                    ? app.instrumentationInfo.packageName
6053                    : app.info.packageName);
6054            if (app.instrumentationClass != null) {
6055                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6056            }
6057            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6058                    + processName + " with config " + mConfiguration);
6059            ApplicationInfo appInfo = app.instrumentationInfo != null
6060                    ? app.instrumentationInfo : app.info;
6061            app.compat = compatibilityInfoForPackageLocked(appInfo);
6062            if (profileFd != null) {
6063                profileFd = profileFd.dup();
6064            }
6065            ProfilerInfo profilerInfo = profileFile == null ? null
6066                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6067            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6068                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6069                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6070                    isRestrictedBackupMode || !normalMode, app.persistent,
6071                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6072                    mCoreSettingsObserver.getCoreSettingsLocked());
6073            updateLruProcessLocked(app, false, null);
6074            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6075        } catch (Exception e) {
6076            // todo: Yikes!  What should we do?  For now we will try to
6077            // start another process, but that could easily get us in
6078            // an infinite loop of restarting processes...
6079            Slog.w(TAG, "Exception thrown during bind!", e);
6080
6081            app.resetPackageList(mProcessStats);
6082            app.unlinkDeathRecipient();
6083            startProcessLocked(app, "bind fail", processName);
6084            return false;
6085        }
6086
6087        // Remove this record from the list of starting applications.
6088        mPersistentStartingProcesses.remove(app);
6089        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6090                "Attach application locked removing on hold: " + app);
6091        mProcessesOnHold.remove(app);
6092
6093        boolean badApp = false;
6094        boolean didSomething = false;
6095
6096        // See if the top visible activity is waiting to run in this process...
6097        if (normalMode) {
6098            try {
6099                if (mStackSupervisor.attachApplicationLocked(app)) {
6100                    didSomething = true;
6101                }
6102            } catch (Exception e) {
6103                badApp = true;
6104            }
6105        }
6106
6107        // Find any services that should be running in this process...
6108        if (!badApp) {
6109            try {
6110                didSomething |= mServices.attachApplicationLocked(app, processName);
6111            } catch (Exception e) {
6112                badApp = true;
6113            }
6114        }
6115
6116        // Check if a next-broadcast receiver is in this process...
6117        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6118            try {
6119                didSomething |= sendPendingBroadcastsLocked(app);
6120            } catch (Exception e) {
6121                // If the app died trying to launch the receiver we declare it 'bad'
6122                badApp = true;
6123            }
6124        }
6125
6126        // Check whether the next backup agent is in this process...
6127        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6128            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6129            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6130            try {
6131                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6132                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6133                        mBackupTarget.backupMode);
6134            } catch (Exception e) {
6135                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6136                e.printStackTrace();
6137            }
6138        }
6139
6140        if (badApp) {
6141            // todo: Also need to kill application to deal with all
6142            // kinds of exceptions.
6143            handleAppDiedLocked(app, false, true);
6144            return false;
6145        }
6146
6147        if (!didSomething) {
6148            updateOomAdjLocked();
6149        }
6150
6151        return true;
6152    }
6153
6154    @Override
6155    public final void attachApplication(IApplicationThread thread) {
6156        synchronized (this) {
6157            int callingPid = Binder.getCallingPid();
6158            final long origId = Binder.clearCallingIdentity();
6159            attachApplicationLocked(thread, callingPid);
6160            Binder.restoreCallingIdentity(origId);
6161        }
6162    }
6163
6164    @Override
6165    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6166        final long origId = Binder.clearCallingIdentity();
6167        synchronized (this) {
6168            ActivityStack stack = ActivityRecord.getStackLocked(token);
6169            if (stack != null) {
6170                ActivityRecord r =
6171                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6172                if (stopProfiling) {
6173                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6174                        try {
6175                            mProfileFd.close();
6176                        } catch (IOException e) {
6177                        }
6178                        clearProfilerLocked();
6179                    }
6180                }
6181            }
6182        }
6183        Binder.restoreCallingIdentity(origId);
6184    }
6185
6186    void postEnableScreenAfterBootLocked() {
6187        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6188    }
6189
6190    void enableScreenAfterBoot() {
6191        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6192                SystemClock.uptimeMillis());
6193        mWindowManager.enableScreenAfterBoot();
6194
6195        synchronized (this) {
6196            updateEventDispatchingLocked();
6197        }
6198    }
6199
6200    @Override
6201    public void showBootMessage(final CharSequence msg, final boolean always) {
6202        enforceNotIsolatedCaller("showBootMessage");
6203        mWindowManager.showBootMessage(msg, always);
6204    }
6205
6206    @Override
6207    public void keyguardWaitingForActivityDrawn() {
6208        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6209        final long token = Binder.clearCallingIdentity();
6210        try {
6211            synchronized (this) {
6212                if (DEBUG_LOCKSCREEN) logLockScreen("");
6213                mWindowManager.keyguardWaitingForActivityDrawn();
6214                mKeyguardWaitingForDraw = true;
6215            }
6216        } finally {
6217            Binder.restoreCallingIdentity(token);
6218        }
6219    }
6220
6221    final void finishBooting() {
6222        synchronized (this) {
6223            if (!mBootAnimationComplete) {
6224                mCallFinishBooting = true;
6225                return;
6226            }
6227            mCallFinishBooting = false;
6228        }
6229
6230        // Register receivers to handle package update events
6231        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6232
6233        // Let system services know.
6234        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6235
6236        synchronized (this) {
6237            // Ensure that any processes we had put on hold are now started
6238            // up.
6239            final int NP = mProcessesOnHold.size();
6240            if (NP > 0) {
6241                ArrayList<ProcessRecord> procs =
6242                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6243                for (int ip=0; ip<NP; ip++) {
6244                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6245                            + procs.get(ip));
6246                    startProcessLocked(procs.get(ip), "on-hold", null);
6247                }
6248            }
6249
6250            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6251                // Start looking for apps that are abusing wake locks.
6252                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6253                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6254                // Tell anyone interested that we are done booting!
6255                SystemProperties.set("sys.boot_completed", "1");
6256                SystemProperties.set("dev.bootcomplete", "1");
6257                for (int i=0; i<mStartedUsers.size(); i++) {
6258                    UserStartedState uss = mStartedUsers.valueAt(i);
6259                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6260                        uss.mState = UserStartedState.STATE_RUNNING;
6261                        final int userId = mStartedUsers.keyAt(i);
6262                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6263                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6264                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6265                        broadcastIntentLocked(null, null, intent, null,
6266                                new IIntentReceiver.Stub() {
6267                                    @Override
6268                                    public void performReceive(Intent intent, int resultCode,
6269                                            String data, Bundle extras, boolean ordered,
6270                                            boolean sticky, int sendingUser) {
6271                                        synchronized (ActivityManagerService.this) {
6272                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6273                                                    true, false);
6274                                        }
6275                                    }
6276                                },
6277                                0, null, null,
6278                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6279                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6280                                userId);
6281                    }
6282                }
6283                scheduleStartProfilesLocked();
6284            }
6285        }
6286    }
6287
6288    @Override
6289    public void bootAnimationComplete() {
6290        final boolean callFinishBooting;
6291        synchronized (this) {
6292            callFinishBooting = mCallFinishBooting;
6293            mBootAnimationComplete = true;
6294        }
6295        if (callFinishBooting) {
6296            finishBooting();
6297        }
6298    }
6299
6300    final void ensureBootCompleted() {
6301        boolean booting;
6302        boolean enableScreen;
6303        synchronized (this) {
6304            booting = mBooting;
6305            mBooting = false;
6306            enableScreen = !mBooted;
6307            mBooted = true;
6308        }
6309
6310        if (booting) {
6311            finishBooting();
6312        }
6313
6314        if (enableScreen) {
6315            enableScreenAfterBoot();
6316        }
6317    }
6318
6319    @Override
6320    public final void activityResumed(IBinder token) {
6321        final long origId = Binder.clearCallingIdentity();
6322        synchronized(this) {
6323            ActivityStack stack = ActivityRecord.getStackLocked(token);
6324            if (stack != null) {
6325                ActivityRecord.activityResumedLocked(token);
6326            }
6327        }
6328        Binder.restoreCallingIdentity(origId);
6329    }
6330
6331    @Override
6332    public final void activityPaused(IBinder token) {
6333        final long origId = Binder.clearCallingIdentity();
6334        synchronized(this) {
6335            ActivityStack stack = ActivityRecord.getStackLocked(token);
6336            if (stack != null) {
6337                stack.activityPausedLocked(token, false);
6338            }
6339        }
6340        Binder.restoreCallingIdentity(origId);
6341    }
6342
6343    @Override
6344    public final void activityStopped(IBinder token, Bundle icicle,
6345            PersistableBundle persistentState, CharSequence description) {
6346        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6347
6348        // Refuse possible leaked file descriptors
6349        if (icicle != null && icicle.hasFileDescriptors()) {
6350            throw new IllegalArgumentException("File descriptors passed in Bundle");
6351        }
6352
6353        final long origId = Binder.clearCallingIdentity();
6354
6355        synchronized (this) {
6356            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6357            if (r != null) {
6358                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6359            }
6360        }
6361
6362        trimApplications();
6363
6364        Binder.restoreCallingIdentity(origId);
6365    }
6366
6367    @Override
6368    public final void activityDestroyed(IBinder token) {
6369        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6370        synchronized (this) {
6371            ActivityStack stack = ActivityRecord.getStackLocked(token);
6372            if (stack != null) {
6373                stack.activityDestroyedLocked(token);
6374            }
6375        }
6376    }
6377
6378    @Override
6379    public final void backgroundResourcesReleased(IBinder token) {
6380        final long origId = Binder.clearCallingIdentity();
6381        try {
6382            synchronized (this) {
6383                ActivityStack stack = ActivityRecord.getStackLocked(token);
6384                if (stack != null) {
6385                    stack.backgroundResourcesReleased(token);
6386                }
6387            }
6388        } finally {
6389            Binder.restoreCallingIdentity(origId);
6390        }
6391    }
6392
6393    @Override
6394    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6395        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6396    }
6397
6398    @Override
6399    public final void notifyEnterAnimationComplete(IBinder token) {
6400        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6401    }
6402
6403    @Override
6404    public String getCallingPackage(IBinder token) {
6405        synchronized (this) {
6406            ActivityRecord r = getCallingRecordLocked(token);
6407            return r != null ? r.info.packageName : null;
6408        }
6409    }
6410
6411    @Override
6412    public ComponentName getCallingActivity(IBinder token) {
6413        synchronized (this) {
6414            ActivityRecord r = getCallingRecordLocked(token);
6415            return r != null ? r.intent.getComponent() : null;
6416        }
6417    }
6418
6419    private ActivityRecord getCallingRecordLocked(IBinder token) {
6420        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6421        if (r == null) {
6422            return null;
6423        }
6424        return r.resultTo;
6425    }
6426
6427    @Override
6428    public ComponentName getActivityClassForToken(IBinder token) {
6429        synchronized(this) {
6430            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6431            if (r == null) {
6432                return null;
6433            }
6434            return r.intent.getComponent();
6435        }
6436    }
6437
6438    @Override
6439    public String getPackageForToken(IBinder token) {
6440        synchronized(this) {
6441            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6442            if (r == null) {
6443                return null;
6444            }
6445            return r.packageName;
6446        }
6447    }
6448
6449    @Override
6450    public IIntentSender getIntentSender(int type,
6451            String packageName, IBinder token, String resultWho,
6452            int requestCode, Intent[] intents, String[] resolvedTypes,
6453            int flags, Bundle options, int userId) {
6454        enforceNotIsolatedCaller("getIntentSender");
6455        // Refuse possible leaked file descriptors
6456        if (intents != null) {
6457            if (intents.length < 1) {
6458                throw new IllegalArgumentException("Intents array length must be >= 1");
6459            }
6460            for (int i=0; i<intents.length; i++) {
6461                Intent intent = intents[i];
6462                if (intent != null) {
6463                    if (intent.hasFileDescriptors()) {
6464                        throw new IllegalArgumentException("File descriptors passed in Intent");
6465                    }
6466                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6467                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6468                        throw new IllegalArgumentException(
6469                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6470                    }
6471                    intents[i] = new Intent(intent);
6472                }
6473            }
6474            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6475                throw new IllegalArgumentException(
6476                        "Intent array length does not match resolvedTypes length");
6477            }
6478        }
6479        if (options != null) {
6480            if (options.hasFileDescriptors()) {
6481                throw new IllegalArgumentException("File descriptors passed in options");
6482            }
6483        }
6484
6485        synchronized(this) {
6486            int callingUid = Binder.getCallingUid();
6487            int origUserId = userId;
6488            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6489                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6490                    ALLOW_NON_FULL, "getIntentSender", null);
6491            if (origUserId == UserHandle.USER_CURRENT) {
6492                // We don't want to evaluate this until the pending intent is
6493                // actually executed.  However, we do want to always do the
6494                // security checking for it above.
6495                userId = UserHandle.USER_CURRENT;
6496            }
6497            try {
6498                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6499                    int uid = AppGlobals.getPackageManager()
6500                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6501                    if (!UserHandle.isSameApp(callingUid, uid)) {
6502                        String msg = "Permission Denial: getIntentSender() from pid="
6503                            + Binder.getCallingPid()
6504                            + ", uid=" + Binder.getCallingUid()
6505                            + ", (need uid=" + uid + ")"
6506                            + " is not allowed to send as package " + packageName;
6507                        Slog.w(TAG, msg);
6508                        throw new SecurityException(msg);
6509                    }
6510                }
6511
6512                return getIntentSenderLocked(type, packageName, callingUid, userId,
6513                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6514
6515            } catch (RemoteException e) {
6516                throw new SecurityException(e);
6517            }
6518        }
6519    }
6520
6521    IIntentSender getIntentSenderLocked(int type, String packageName,
6522            int callingUid, int userId, IBinder token, String resultWho,
6523            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6524            Bundle options) {
6525        if (DEBUG_MU)
6526            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6527        ActivityRecord activity = null;
6528        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6529            activity = ActivityRecord.isInStackLocked(token);
6530            if (activity == null) {
6531                return null;
6532            }
6533            if (activity.finishing) {
6534                return null;
6535            }
6536        }
6537
6538        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6539        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6540        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6541        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6542                |PendingIntent.FLAG_UPDATE_CURRENT);
6543
6544        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6545                type, packageName, activity, resultWho,
6546                requestCode, intents, resolvedTypes, flags, options, userId);
6547        WeakReference<PendingIntentRecord> ref;
6548        ref = mIntentSenderRecords.get(key);
6549        PendingIntentRecord rec = ref != null ? ref.get() : null;
6550        if (rec != null) {
6551            if (!cancelCurrent) {
6552                if (updateCurrent) {
6553                    if (rec.key.requestIntent != null) {
6554                        rec.key.requestIntent.replaceExtras(intents != null ?
6555                                intents[intents.length - 1] : null);
6556                    }
6557                    if (intents != null) {
6558                        intents[intents.length-1] = rec.key.requestIntent;
6559                        rec.key.allIntents = intents;
6560                        rec.key.allResolvedTypes = resolvedTypes;
6561                    } else {
6562                        rec.key.allIntents = null;
6563                        rec.key.allResolvedTypes = null;
6564                    }
6565                }
6566                return rec;
6567            }
6568            rec.canceled = true;
6569            mIntentSenderRecords.remove(key);
6570        }
6571        if (noCreate) {
6572            return rec;
6573        }
6574        rec = new PendingIntentRecord(this, key, callingUid);
6575        mIntentSenderRecords.put(key, rec.ref);
6576        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6577            if (activity.pendingResults == null) {
6578                activity.pendingResults
6579                        = new HashSet<WeakReference<PendingIntentRecord>>();
6580            }
6581            activity.pendingResults.add(rec.ref);
6582        }
6583        return rec;
6584    }
6585
6586    @Override
6587    public void cancelIntentSender(IIntentSender sender) {
6588        if (!(sender instanceof PendingIntentRecord)) {
6589            return;
6590        }
6591        synchronized(this) {
6592            PendingIntentRecord rec = (PendingIntentRecord)sender;
6593            try {
6594                int uid = AppGlobals.getPackageManager()
6595                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6596                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6597                    String msg = "Permission Denial: cancelIntentSender() from pid="
6598                        + Binder.getCallingPid()
6599                        + ", uid=" + Binder.getCallingUid()
6600                        + " is not allowed to cancel packges "
6601                        + rec.key.packageName;
6602                    Slog.w(TAG, msg);
6603                    throw new SecurityException(msg);
6604                }
6605            } catch (RemoteException e) {
6606                throw new SecurityException(e);
6607            }
6608            cancelIntentSenderLocked(rec, true);
6609        }
6610    }
6611
6612    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6613        rec.canceled = true;
6614        mIntentSenderRecords.remove(rec.key);
6615        if (cleanActivity && rec.key.activity != null) {
6616            rec.key.activity.pendingResults.remove(rec.ref);
6617        }
6618    }
6619
6620    @Override
6621    public String getPackageForIntentSender(IIntentSender pendingResult) {
6622        if (!(pendingResult instanceof PendingIntentRecord)) {
6623            return null;
6624        }
6625        try {
6626            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6627            return res.key.packageName;
6628        } catch (ClassCastException e) {
6629        }
6630        return null;
6631    }
6632
6633    @Override
6634    public int getUidForIntentSender(IIntentSender sender) {
6635        if (sender instanceof PendingIntentRecord) {
6636            try {
6637                PendingIntentRecord res = (PendingIntentRecord)sender;
6638                return res.uid;
6639            } catch (ClassCastException e) {
6640            }
6641        }
6642        return -1;
6643    }
6644
6645    @Override
6646    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6647        if (!(pendingResult instanceof PendingIntentRecord)) {
6648            return false;
6649        }
6650        try {
6651            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6652            if (res.key.allIntents == null) {
6653                return false;
6654            }
6655            for (int i=0; i<res.key.allIntents.length; i++) {
6656                Intent intent = res.key.allIntents[i];
6657                if (intent.getPackage() != null && intent.getComponent() != null) {
6658                    return false;
6659                }
6660            }
6661            return true;
6662        } catch (ClassCastException e) {
6663        }
6664        return false;
6665    }
6666
6667    @Override
6668    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6669        if (!(pendingResult instanceof PendingIntentRecord)) {
6670            return false;
6671        }
6672        try {
6673            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6674            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6675                return true;
6676            }
6677            return false;
6678        } catch (ClassCastException e) {
6679        }
6680        return false;
6681    }
6682
6683    @Override
6684    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6685        if (!(pendingResult instanceof PendingIntentRecord)) {
6686            return null;
6687        }
6688        try {
6689            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6690            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6691        } catch (ClassCastException e) {
6692        }
6693        return null;
6694    }
6695
6696    @Override
6697    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6698        if (!(pendingResult instanceof PendingIntentRecord)) {
6699            return null;
6700        }
6701        try {
6702            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6703            Intent intent = res.key.requestIntent;
6704            if (intent != null) {
6705                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6706                        || res.lastTagPrefix.equals(prefix))) {
6707                    return res.lastTag;
6708                }
6709                res.lastTagPrefix = prefix;
6710                StringBuilder sb = new StringBuilder(128);
6711                if (prefix != null) {
6712                    sb.append(prefix);
6713                }
6714                if (intent.getAction() != null) {
6715                    sb.append(intent.getAction());
6716                } else if (intent.getComponent() != null) {
6717                    intent.getComponent().appendShortString(sb);
6718                } else {
6719                    sb.append("?");
6720                }
6721                return res.lastTag = sb.toString();
6722            }
6723        } catch (ClassCastException e) {
6724        }
6725        return null;
6726    }
6727
6728    @Override
6729    public void setProcessLimit(int max) {
6730        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6731                "setProcessLimit()");
6732        synchronized (this) {
6733            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6734            mProcessLimitOverride = max;
6735        }
6736        trimApplications();
6737    }
6738
6739    @Override
6740    public int getProcessLimit() {
6741        synchronized (this) {
6742            return mProcessLimitOverride;
6743        }
6744    }
6745
6746    void foregroundTokenDied(ForegroundToken token) {
6747        synchronized (ActivityManagerService.this) {
6748            synchronized (mPidsSelfLocked) {
6749                ForegroundToken cur
6750                    = mForegroundProcesses.get(token.pid);
6751                if (cur != token) {
6752                    return;
6753                }
6754                mForegroundProcesses.remove(token.pid);
6755                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6756                if (pr == null) {
6757                    return;
6758                }
6759                pr.forcingToForeground = null;
6760                updateProcessForegroundLocked(pr, false, false);
6761            }
6762            updateOomAdjLocked();
6763        }
6764    }
6765
6766    @Override
6767    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6768        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6769                "setProcessForeground()");
6770        synchronized(this) {
6771            boolean changed = false;
6772
6773            synchronized (mPidsSelfLocked) {
6774                ProcessRecord pr = mPidsSelfLocked.get(pid);
6775                if (pr == null && isForeground) {
6776                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6777                    return;
6778                }
6779                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6780                if (oldToken != null) {
6781                    oldToken.token.unlinkToDeath(oldToken, 0);
6782                    mForegroundProcesses.remove(pid);
6783                    if (pr != null) {
6784                        pr.forcingToForeground = null;
6785                    }
6786                    changed = true;
6787                }
6788                if (isForeground && token != null) {
6789                    ForegroundToken newToken = new ForegroundToken() {
6790                        @Override
6791                        public void binderDied() {
6792                            foregroundTokenDied(this);
6793                        }
6794                    };
6795                    newToken.pid = pid;
6796                    newToken.token = token;
6797                    try {
6798                        token.linkToDeath(newToken, 0);
6799                        mForegroundProcesses.put(pid, newToken);
6800                        pr.forcingToForeground = token;
6801                        changed = true;
6802                    } catch (RemoteException e) {
6803                        // If the process died while doing this, we will later
6804                        // do the cleanup with the process death link.
6805                    }
6806                }
6807            }
6808
6809            if (changed) {
6810                updateOomAdjLocked();
6811            }
6812        }
6813    }
6814
6815    // =========================================================
6816    // PERMISSIONS
6817    // =========================================================
6818
6819    static class PermissionController extends IPermissionController.Stub {
6820        ActivityManagerService mActivityManagerService;
6821        PermissionController(ActivityManagerService activityManagerService) {
6822            mActivityManagerService = activityManagerService;
6823        }
6824
6825        @Override
6826        public boolean checkPermission(String permission, int pid, int uid) {
6827            return mActivityManagerService.checkPermission(permission, pid,
6828                    uid) == PackageManager.PERMISSION_GRANTED;
6829        }
6830    }
6831
6832    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6833        @Override
6834        public int checkComponentPermission(String permission, int pid, int uid,
6835                int owningUid, boolean exported) {
6836            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6837                    owningUid, exported);
6838        }
6839
6840        @Override
6841        public Object getAMSLock() {
6842            return ActivityManagerService.this;
6843        }
6844    }
6845
6846    /**
6847     * This can be called with or without the global lock held.
6848     */
6849    int checkComponentPermission(String permission, int pid, int uid,
6850            int owningUid, boolean exported) {
6851        // We might be performing an operation on behalf of an indirect binder
6852        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6853        // client identity accordingly before proceeding.
6854        Identity tlsIdentity = sCallerIdentity.get();
6855        if (tlsIdentity != null) {
6856            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6857                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6858            uid = tlsIdentity.uid;
6859            pid = tlsIdentity.pid;
6860        }
6861
6862        if (pid == MY_PID) {
6863            return PackageManager.PERMISSION_GRANTED;
6864        }
6865
6866        return ActivityManager.checkComponentPermission(permission, uid,
6867                owningUid, exported);
6868    }
6869
6870    /**
6871     * As the only public entry point for permissions checking, this method
6872     * can enforce the semantic that requesting a check on a null global
6873     * permission is automatically denied.  (Internally a null permission
6874     * string is used when calling {@link #checkComponentPermission} in cases
6875     * when only uid-based security is needed.)
6876     *
6877     * This can be called with or without the global lock held.
6878     */
6879    @Override
6880    public int checkPermission(String permission, int pid, int uid) {
6881        if (permission == null) {
6882            return PackageManager.PERMISSION_DENIED;
6883        }
6884        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6885    }
6886
6887    /**
6888     * Binder IPC calls go through the public entry point.
6889     * This can be called with or without the global lock held.
6890     */
6891    int checkCallingPermission(String permission) {
6892        return checkPermission(permission,
6893                Binder.getCallingPid(),
6894                UserHandle.getAppId(Binder.getCallingUid()));
6895    }
6896
6897    /**
6898     * This can be called with or without the global lock held.
6899     */
6900    void enforceCallingPermission(String permission, String func) {
6901        if (checkCallingPermission(permission)
6902                == PackageManager.PERMISSION_GRANTED) {
6903            return;
6904        }
6905
6906        String msg = "Permission Denial: " + func + " from pid="
6907                + Binder.getCallingPid()
6908                + ", uid=" + Binder.getCallingUid()
6909                + " requires " + permission;
6910        Slog.w(TAG, msg);
6911        throw new SecurityException(msg);
6912    }
6913
6914    /**
6915     * Determine if UID is holding permissions required to access {@link Uri} in
6916     * the given {@link ProviderInfo}. Final permission checking is always done
6917     * in {@link ContentProvider}.
6918     */
6919    private final boolean checkHoldingPermissionsLocked(
6920            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6921        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6922                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6923        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6924            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6925                    != PERMISSION_GRANTED) {
6926                return false;
6927            }
6928        }
6929        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6930    }
6931
6932    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6933            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6934        if (pi.applicationInfo.uid == uid) {
6935            return true;
6936        } else if (!pi.exported) {
6937            return false;
6938        }
6939
6940        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6941        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6942        try {
6943            // check if target holds top-level <provider> permissions
6944            if (!readMet && pi.readPermission != null && considerUidPermissions
6945                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6946                readMet = true;
6947            }
6948            if (!writeMet && pi.writePermission != null && considerUidPermissions
6949                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6950                writeMet = true;
6951            }
6952
6953            // track if unprotected read/write is allowed; any denied
6954            // <path-permission> below removes this ability
6955            boolean allowDefaultRead = pi.readPermission == null;
6956            boolean allowDefaultWrite = pi.writePermission == null;
6957
6958            // check if target holds any <path-permission> that match uri
6959            final PathPermission[] pps = pi.pathPermissions;
6960            if (pps != null) {
6961                final String path = grantUri.uri.getPath();
6962                int i = pps.length;
6963                while (i > 0 && (!readMet || !writeMet)) {
6964                    i--;
6965                    PathPermission pp = pps[i];
6966                    if (pp.match(path)) {
6967                        if (!readMet) {
6968                            final String pprperm = pp.getReadPermission();
6969                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6970                                    + pprperm + " for " + pp.getPath()
6971                                    + ": match=" + pp.match(path)
6972                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6973                            if (pprperm != null) {
6974                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6975                                        == PERMISSION_GRANTED) {
6976                                    readMet = true;
6977                                } else {
6978                                    allowDefaultRead = false;
6979                                }
6980                            }
6981                        }
6982                        if (!writeMet) {
6983                            final String ppwperm = pp.getWritePermission();
6984                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6985                                    + ppwperm + " for " + pp.getPath()
6986                                    + ": match=" + pp.match(path)
6987                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6988                            if (ppwperm != null) {
6989                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6990                                        == PERMISSION_GRANTED) {
6991                                    writeMet = true;
6992                                } else {
6993                                    allowDefaultWrite = false;
6994                                }
6995                            }
6996                        }
6997                    }
6998                }
6999            }
7000
7001            // grant unprotected <provider> read/write, if not blocked by
7002            // <path-permission> above
7003            if (allowDefaultRead) readMet = true;
7004            if (allowDefaultWrite) writeMet = true;
7005
7006        } catch (RemoteException e) {
7007            return false;
7008        }
7009
7010        return readMet && writeMet;
7011    }
7012
7013    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7014        ProviderInfo pi = null;
7015        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7016        if (cpr != null) {
7017            pi = cpr.info;
7018        } else {
7019            try {
7020                pi = AppGlobals.getPackageManager().resolveContentProvider(
7021                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7022            } catch (RemoteException ex) {
7023            }
7024        }
7025        return pi;
7026    }
7027
7028    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7029        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7030        if (targetUris != null) {
7031            return targetUris.get(grantUri);
7032        }
7033        return null;
7034    }
7035
7036    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7037            String targetPkg, int targetUid, GrantUri grantUri) {
7038        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7039        if (targetUris == null) {
7040            targetUris = Maps.newArrayMap();
7041            mGrantedUriPermissions.put(targetUid, targetUris);
7042        }
7043
7044        UriPermission perm = targetUris.get(grantUri);
7045        if (perm == null) {
7046            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7047            targetUris.put(grantUri, perm);
7048        }
7049
7050        return perm;
7051    }
7052
7053    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7054            final int modeFlags) {
7055        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7056        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7057                : UriPermission.STRENGTH_OWNED;
7058
7059        // Root gets to do everything.
7060        if (uid == 0) {
7061            return true;
7062        }
7063
7064        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7065        if (perms == null) return false;
7066
7067        // First look for exact match
7068        final UriPermission exactPerm = perms.get(grantUri);
7069        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7070            return true;
7071        }
7072
7073        // No exact match, look for prefixes
7074        final int N = perms.size();
7075        for (int i = 0; i < N; i++) {
7076            final UriPermission perm = perms.valueAt(i);
7077            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7078                    && perm.getStrength(modeFlags) >= minStrength) {
7079                return true;
7080            }
7081        }
7082
7083        return false;
7084    }
7085
7086    /**
7087     * @param uri This uri must NOT contain an embedded userId.
7088     * @param userId The userId in which the uri is to be resolved.
7089     */
7090    @Override
7091    public int checkUriPermission(Uri uri, int pid, int uid,
7092            final int modeFlags, int userId) {
7093        enforceNotIsolatedCaller("checkUriPermission");
7094
7095        // Another redirected-binder-call permissions check as in
7096        // {@link checkComponentPermission}.
7097        Identity tlsIdentity = sCallerIdentity.get();
7098        if (tlsIdentity != null) {
7099            uid = tlsIdentity.uid;
7100            pid = tlsIdentity.pid;
7101        }
7102
7103        // Our own process gets to do everything.
7104        if (pid == MY_PID) {
7105            return PackageManager.PERMISSION_GRANTED;
7106        }
7107        synchronized (this) {
7108            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7109                    ? PackageManager.PERMISSION_GRANTED
7110                    : PackageManager.PERMISSION_DENIED;
7111        }
7112    }
7113
7114    /**
7115     * Check if the targetPkg can be granted permission to access uri by
7116     * the callingUid using the given modeFlags.  Throws a security exception
7117     * if callingUid is not allowed to do this.  Returns the uid of the target
7118     * if the URI permission grant should be performed; returns -1 if it is not
7119     * needed (for example targetPkg already has permission to access the URI).
7120     * If you already know the uid of the target, you can supply it in
7121     * lastTargetUid else set that to -1.
7122     */
7123    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7124            final int modeFlags, int lastTargetUid) {
7125        if (!Intent.isAccessUriMode(modeFlags)) {
7126            return -1;
7127        }
7128
7129        if (targetPkg != null) {
7130            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7131                    "Checking grant " + targetPkg + " permission to " + grantUri);
7132        }
7133
7134        final IPackageManager pm = AppGlobals.getPackageManager();
7135
7136        // If this is not a content: uri, we can't do anything with it.
7137        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7138            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7139                    "Can't grant URI permission for non-content URI: " + grantUri);
7140            return -1;
7141        }
7142
7143        final String authority = grantUri.uri.getAuthority();
7144        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7145        if (pi == null) {
7146            Slog.w(TAG, "No content provider found for permission check: " +
7147                    grantUri.uri.toSafeString());
7148            return -1;
7149        }
7150
7151        int targetUid = lastTargetUid;
7152        if (targetUid < 0 && targetPkg != null) {
7153            try {
7154                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7155                if (targetUid < 0) {
7156                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7157                            "Can't grant URI permission no uid for: " + targetPkg);
7158                    return -1;
7159                }
7160            } catch (RemoteException ex) {
7161                return -1;
7162            }
7163        }
7164
7165        if (targetUid >= 0) {
7166            // First...  does the target actually need this permission?
7167            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7168                // No need to grant the target this permission.
7169                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7170                        "Target " + targetPkg + " already has full permission to " + grantUri);
7171                return -1;
7172            }
7173        } else {
7174            // First...  there is no target package, so can anyone access it?
7175            boolean allowed = pi.exported;
7176            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7177                if (pi.readPermission != null) {
7178                    allowed = false;
7179                }
7180            }
7181            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7182                if (pi.writePermission != null) {
7183                    allowed = false;
7184                }
7185            }
7186            if (allowed) {
7187                return -1;
7188            }
7189        }
7190
7191        /* There is a special cross user grant if:
7192         * - The target is on another user.
7193         * - Apps on the current user can access the uri without any uid permissions.
7194         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7195         * grant uri permissions.
7196         */
7197        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7198                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7199                modeFlags, false /*without considering the uid permissions*/);
7200
7201        // Second...  is the provider allowing granting of URI permissions?
7202        if (!specialCrossUserGrant) {
7203            if (!pi.grantUriPermissions) {
7204                throw new SecurityException("Provider " + pi.packageName
7205                        + "/" + pi.name
7206                        + " does not allow granting of Uri permissions (uri "
7207                        + grantUri + ")");
7208            }
7209            if (pi.uriPermissionPatterns != null) {
7210                final int N = pi.uriPermissionPatterns.length;
7211                boolean allowed = false;
7212                for (int i=0; i<N; i++) {
7213                    if (pi.uriPermissionPatterns[i] != null
7214                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7215                        allowed = true;
7216                        break;
7217                    }
7218                }
7219                if (!allowed) {
7220                    throw new SecurityException("Provider " + pi.packageName
7221                            + "/" + pi.name
7222                            + " does not allow granting of permission to path of Uri "
7223                            + grantUri);
7224                }
7225            }
7226        }
7227
7228        // Third...  does the caller itself have permission to access
7229        // this uri?
7230        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7231            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7232                // Require they hold a strong enough Uri permission
7233                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7234                    throw new SecurityException("Uid " + callingUid
7235                            + " does not have permission to uri " + grantUri);
7236                }
7237            }
7238        }
7239        return targetUid;
7240    }
7241
7242    /**
7243     * @param uri This uri must NOT contain an embedded userId.
7244     * @param userId The userId in which the uri is to be resolved.
7245     */
7246    @Override
7247    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7248            final int modeFlags, int userId) {
7249        enforceNotIsolatedCaller("checkGrantUriPermission");
7250        synchronized(this) {
7251            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7252                    new GrantUri(userId, uri, false), modeFlags, -1);
7253        }
7254    }
7255
7256    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7257            final int modeFlags, UriPermissionOwner owner) {
7258        if (!Intent.isAccessUriMode(modeFlags)) {
7259            return;
7260        }
7261
7262        // So here we are: the caller has the assumed permission
7263        // to the uri, and the target doesn't.  Let's now give this to
7264        // the target.
7265
7266        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7267                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7268
7269        final String authority = grantUri.uri.getAuthority();
7270        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7271        if (pi == null) {
7272            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7273            return;
7274        }
7275
7276        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7277            grantUri.prefix = true;
7278        }
7279        final UriPermission perm = findOrCreateUriPermissionLocked(
7280                pi.packageName, targetPkg, targetUid, grantUri);
7281        perm.grantModes(modeFlags, owner);
7282    }
7283
7284    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7285            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7286        if (targetPkg == null) {
7287            throw new NullPointerException("targetPkg");
7288        }
7289        int targetUid;
7290        final IPackageManager pm = AppGlobals.getPackageManager();
7291        try {
7292            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7293        } catch (RemoteException ex) {
7294            return;
7295        }
7296
7297        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7298                targetUid);
7299        if (targetUid < 0) {
7300            return;
7301        }
7302
7303        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7304                owner);
7305    }
7306
7307    static class NeededUriGrants extends ArrayList<GrantUri> {
7308        final String targetPkg;
7309        final int targetUid;
7310        final int flags;
7311
7312        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7313            this.targetPkg = targetPkg;
7314            this.targetUid = targetUid;
7315            this.flags = flags;
7316        }
7317    }
7318
7319    /**
7320     * Like checkGrantUriPermissionLocked, but takes an Intent.
7321     */
7322    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7323            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7324        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7325                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7326                + " clip=" + (intent != null ? intent.getClipData() : null)
7327                + " from " + intent + "; flags=0x"
7328                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7329
7330        if (targetPkg == null) {
7331            throw new NullPointerException("targetPkg");
7332        }
7333
7334        if (intent == null) {
7335            return null;
7336        }
7337        Uri data = intent.getData();
7338        ClipData clip = intent.getClipData();
7339        if (data == null && clip == null) {
7340            return null;
7341        }
7342        // Default userId for uris in the intent (if they don't specify it themselves)
7343        int contentUserHint = intent.getContentUserHint();
7344        if (contentUserHint == UserHandle.USER_CURRENT) {
7345            contentUserHint = UserHandle.getUserId(callingUid);
7346        }
7347        final IPackageManager pm = AppGlobals.getPackageManager();
7348        int targetUid;
7349        if (needed != null) {
7350            targetUid = needed.targetUid;
7351        } else {
7352            try {
7353                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7354            } catch (RemoteException ex) {
7355                return null;
7356            }
7357            if (targetUid < 0) {
7358                if (DEBUG_URI_PERMISSION) {
7359                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7360                            + " on user " + targetUserId);
7361                }
7362                return null;
7363            }
7364        }
7365        if (data != null) {
7366            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7367            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7368                    targetUid);
7369            if (targetUid > 0) {
7370                if (needed == null) {
7371                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7372                }
7373                needed.add(grantUri);
7374            }
7375        }
7376        if (clip != null) {
7377            for (int i=0; i<clip.getItemCount(); i++) {
7378                Uri uri = clip.getItemAt(i).getUri();
7379                if (uri != null) {
7380                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7381                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7382                            targetUid);
7383                    if (targetUid > 0) {
7384                        if (needed == null) {
7385                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7386                        }
7387                        needed.add(grantUri);
7388                    }
7389                } else {
7390                    Intent clipIntent = clip.getItemAt(i).getIntent();
7391                    if (clipIntent != null) {
7392                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7393                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7394                        if (newNeeded != null) {
7395                            needed = newNeeded;
7396                        }
7397                    }
7398                }
7399            }
7400        }
7401
7402        return needed;
7403    }
7404
7405    /**
7406     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7407     */
7408    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7409            UriPermissionOwner owner) {
7410        if (needed != null) {
7411            for (int i=0; i<needed.size(); i++) {
7412                GrantUri grantUri = needed.get(i);
7413                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7414                        grantUri, needed.flags, owner);
7415            }
7416        }
7417    }
7418
7419    void grantUriPermissionFromIntentLocked(int callingUid,
7420            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7421        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7422                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7423        if (needed == null) {
7424            return;
7425        }
7426
7427        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7428    }
7429
7430    /**
7431     * @param uri This uri must NOT contain an embedded userId.
7432     * @param userId The userId in which the uri is to be resolved.
7433     */
7434    @Override
7435    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7436            final int modeFlags, int userId) {
7437        enforceNotIsolatedCaller("grantUriPermission");
7438        GrantUri grantUri = new GrantUri(userId, uri, false);
7439        synchronized(this) {
7440            final ProcessRecord r = getRecordForAppLocked(caller);
7441            if (r == null) {
7442                throw new SecurityException("Unable to find app for caller "
7443                        + caller
7444                        + " when granting permission to uri " + grantUri);
7445            }
7446            if (targetPkg == null) {
7447                throw new IllegalArgumentException("null target");
7448            }
7449            if (grantUri == null) {
7450                throw new IllegalArgumentException("null uri");
7451            }
7452
7453            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7454                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7455                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7456                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7457
7458            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7459                    UserHandle.getUserId(r.uid));
7460        }
7461    }
7462
7463    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7464        if (perm.modeFlags == 0) {
7465            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7466                    perm.targetUid);
7467            if (perms != null) {
7468                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7469                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7470
7471                perms.remove(perm.uri);
7472                if (perms.isEmpty()) {
7473                    mGrantedUriPermissions.remove(perm.targetUid);
7474                }
7475            }
7476        }
7477    }
7478
7479    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7480        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7481
7482        final IPackageManager pm = AppGlobals.getPackageManager();
7483        final String authority = grantUri.uri.getAuthority();
7484        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7485        if (pi == null) {
7486            Slog.w(TAG, "No content provider found for permission revoke: "
7487                    + grantUri.toSafeString());
7488            return;
7489        }
7490
7491        // Does the caller have this permission on the URI?
7492        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7493            // Have they don't have direct access to the URI, then revoke any URI
7494            // permissions that have been granted to them.
7495            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7496            if (perms != null) {
7497                boolean persistChanged = false;
7498                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7499                    final UriPermission perm = it.next();
7500                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7501                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7502                        if (DEBUG_URI_PERMISSION)
7503                            Slog.v(TAG,
7504                                    "Revoking " + perm.targetUid + " permission to " + perm.uri);
7505                        persistChanged |= perm.revokeModes(
7506                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7507                        if (perm.modeFlags == 0) {
7508                            it.remove();
7509                        }
7510                    }
7511                }
7512                if (perms.isEmpty()) {
7513                    mGrantedUriPermissions.remove(callingUid);
7514                }
7515                if (persistChanged) {
7516                    schedulePersistUriGrants();
7517                }
7518            }
7519            return;
7520        }
7521
7522        boolean persistChanged = false;
7523
7524        // Go through all of the permissions and remove any that match.
7525        int N = mGrantedUriPermissions.size();
7526        for (int i = 0; i < N; i++) {
7527            final int targetUid = mGrantedUriPermissions.keyAt(i);
7528            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7529
7530            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7531                final UriPermission perm = it.next();
7532                if (perm.uri.sourceUserId == grantUri.sourceUserId
7533                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7534                    if (DEBUG_URI_PERMISSION)
7535                        Slog.v(TAG,
7536                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7537                    persistChanged |= perm.revokeModes(
7538                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7539                    if (perm.modeFlags == 0) {
7540                        it.remove();
7541                    }
7542                }
7543            }
7544
7545            if (perms.isEmpty()) {
7546                mGrantedUriPermissions.remove(targetUid);
7547                N--;
7548                i--;
7549            }
7550        }
7551
7552        if (persistChanged) {
7553            schedulePersistUriGrants();
7554        }
7555    }
7556
7557    /**
7558     * @param uri This uri must NOT contain an embedded userId.
7559     * @param userId The userId in which the uri is to be resolved.
7560     */
7561    @Override
7562    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7563            int userId) {
7564        enforceNotIsolatedCaller("revokeUriPermission");
7565        synchronized(this) {
7566            final ProcessRecord r = getRecordForAppLocked(caller);
7567            if (r == null) {
7568                throw new SecurityException("Unable to find app for caller "
7569                        + caller
7570                        + " when revoking permission to uri " + uri);
7571            }
7572            if (uri == null) {
7573                Slog.w(TAG, "revokeUriPermission: null uri");
7574                return;
7575            }
7576
7577            if (!Intent.isAccessUriMode(modeFlags)) {
7578                return;
7579            }
7580
7581            final IPackageManager pm = AppGlobals.getPackageManager();
7582            final String authority = uri.getAuthority();
7583            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7584            if (pi == null) {
7585                Slog.w(TAG, "No content provider found for permission revoke: "
7586                        + uri.toSafeString());
7587                return;
7588            }
7589
7590            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7591        }
7592    }
7593
7594    /**
7595     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7596     * given package.
7597     *
7598     * @param packageName Package name to match, or {@code null} to apply to all
7599     *            packages.
7600     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7601     *            to all users.
7602     * @param persistable If persistable grants should be removed.
7603     */
7604    private void removeUriPermissionsForPackageLocked(
7605            String packageName, int userHandle, boolean persistable) {
7606        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7607            throw new IllegalArgumentException("Must narrow by either package or user");
7608        }
7609
7610        boolean persistChanged = false;
7611
7612        int N = mGrantedUriPermissions.size();
7613        for (int i = 0; i < N; i++) {
7614            final int targetUid = mGrantedUriPermissions.keyAt(i);
7615            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7616
7617            // Only inspect grants matching user
7618            if (userHandle == UserHandle.USER_ALL
7619                    || userHandle == UserHandle.getUserId(targetUid)) {
7620                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7621                    final UriPermission perm = it.next();
7622
7623                    // Only inspect grants matching package
7624                    if (packageName == null || perm.sourcePkg.equals(packageName)
7625                            || perm.targetPkg.equals(packageName)) {
7626                        persistChanged |= perm.revokeModes(
7627                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7628
7629                        // Only remove when no modes remain; any persisted grants
7630                        // will keep this alive.
7631                        if (perm.modeFlags == 0) {
7632                            it.remove();
7633                        }
7634                    }
7635                }
7636
7637                if (perms.isEmpty()) {
7638                    mGrantedUriPermissions.remove(targetUid);
7639                    N--;
7640                    i--;
7641                }
7642            }
7643        }
7644
7645        if (persistChanged) {
7646            schedulePersistUriGrants();
7647        }
7648    }
7649
7650    @Override
7651    public IBinder newUriPermissionOwner(String name) {
7652        enforceNotIsolatedCaller("newUriPermissionOwner");
7653        synchronized(this) {
7654            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7655            return owner.getExternalTokenLocked();
7656        }
7657    }
7658
7659    /**
7660     * @param uri This uri must NOT contain an embedded userId.
7661     * @param sourceUserId The userId in which the uri is to be resolved.
7662     * @param targetUserId The userId of the app that receives the grant.
7663     */
7664    @Override
7665    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7666            final int modeFlags, int sourceUserId, int targetUserId) {
7667        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7668                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7669        synchronized(this) {
7670            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7671            if (owner == null) {
7672                throw new IllegalArgumentException("Unknown owner: " + token);
7673            }
7674            if (fromUid != Binder.getCallingUid()) {
7675                if (Binder.getCallingUid() != Process.myUid()) {
7676                    // Only system code can grant URI permissions on behalf
7677                    // of other users.
7678                    throw new SecurityException("nice try");
7679                }
7680            }
7681            if (targetPkg == null) {
7682                throw new IllegalArgumentException("null target");
7683            }
7684            if (uri == null) {
7685                throw new IllegalArgumentException("null uri");
7686            }
7687
7688            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7689                    modeFlags, owner, targetUserId);
7690        }
7691    }
7692
7693    /**
7694     * @param uri This uri must NOT contain an embedded userId.
7695     * @param userId The userId in which the uri is to be resolved.
7696     */
7697    @Override
7698    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7699        synchronized(this) {
7700            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7701            if (owner == null) {
7702                throw new IllegalArgumentException("Unknown owner: " + token);
7703            }
7704
7705            if (uri == null) {
7706                owner.removeUriPermissionsLocked(mode);
7707            } else {
7708                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7709            }
7710        }
7711    }
7712
7713    private void schedulePersistUriGrants() {
7714        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7715            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7716                    10 * DateUtils.SECOND_IN_MILLIS);
7717        }
7718    }
7719
7720    private void writeGrantedUriPermissions() {
7721        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7722
7723        // Snapshot permissions so we can persist without lock
7724        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7725        synchronized (this) {
7726            final int size = mGrantedUriPermissions.size();
7727            for (int i = 0; i < size; i++) {
7728                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7729                for (UriPermission perm : perms.values()) {
7730                    if (perm.persistedModeFlags != 0) {
7731                        persist.add(perm.snapshot());
7732                    }
7733                }
7734            }
7735        }
7736
7737        FileOutputStream fos = null;
7738        try {
7739            fos = mGrantFile.startWrite();
7740
7741            XmlSerializer out = new FastXmlSerializer();
7742            out.setOutput(fos, "utf-8");
7743            out.startDocument(null, true);
7744            out.startTag(null, TAG_URI_GRANTS);
7745            for (UriPermission.Snapshot perm : persist) {
7746                out.startTag(null, TAG_URI_GRANT);
7747                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7748                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7749                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7750                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7751                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7752                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7753                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7754                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7755                out.endTag(null, TAG_URI_GRANT);
7756            }
7757            out.endTag(null, TAG_URI_GRANTS);
7758            out.endDocument();
7759
7760            mGrantFile.finishWrite(fos);
7761        } catch (IOException e) {
7762            if (fos != null) {
7763                mGrantFile.failWrite(fos);
7764            }
7765        }
7766    }
7767
7768    private void readGrantedUriPermissionsLocked() {
7769        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7770
7771        final long now = System.currentTimeMillis();
7772
7773        FileInputStream fis = null;
7774        try {
7775            fis = mGrantFile.openRead();
7776            final XmlPullParser in = Xml.newPullParser();
7777            in.setInput(fis, null);
7778
7779            int type;
7780            while ((type = in.next()) != END_DOCUMENT) {
7781                final String tag = in.getName();
7782                if (type == START_TAG) {
7783                    if (TAG_URI_GRANT.equals(tag)) {
7784                        final int sourceUserId;
7785                        final int targetUserId;
7786                        final int userHandle = readIntAttribute(in,
7787                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7788                        if (userHandle != UserHandle.USER_NULL) {
7789                            // For backwards compatibility.
7790                            sourceUserId = userHandle;
7791                            targetUserId = userHandle;
7792                        } else {
7793                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7794                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7795                        }
7796                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7797                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7798                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7799                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7800                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7801                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7802
7803                        // Sanity check that provider still belongs to source package
7804                        final ProviderInfo pi = getProviderInfoLocked(
7805                                uri.getAuthority(), sourceUserId);
7806                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7807                            int targetUid = -1;
7808                            try {
7809                                targetUid = AppGlobals.getPackageManager()
7810                                        .getPackageUid(targetPkg, targetUserId);
7811                            } catch (RemoteException e) {
7812                            }
7813                            if (targetUid != -1) {
7814                                final UriPermission perm = findOrCreateUriPermissionLocked(
7815                                        sourcePkg, targetPkg, targetUid,
7816                                        new GrantUri(sourceUserId, uri, prefix));
7817                                perm.initPersistedModes(modeFlags, createdTime);
7818                            }
7819                        } else {
7820                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7821                                    + " but instead found " + pi);
7822                        }
7823                    }
7824                }
7825            }
7826        } catch (FileNotFoundException e) {
7827            // Missing grants is okay
7828        } catch (IOException e) {
7829            Log.wtf(TAG, "Failed reading Uri grants", e);
7830        } catch (XmlPullParserException e) {
7831            Log.wtf(TAG, "Failed reading Uri grants", e);
7832        } finally {
7833            IoUtils.closeQuietly(fis);
7834        }
7835    }
7836
7837    /**
7838     * @param uri This uri must NOT contain an embedded userId.
7839     * @param userId The userId in which the uri is to be resolved.
7840     */
7841    @Override
7842    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7843        enforceNotIsolatedCaller("takePersistableUriPermission");
7844
7845        Preconditions.checkFlagsArgument(modeFlags,
7846                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7847
7848        synchronized (this) {
7849            final int callingUid = Binder.getCallingUid();
7850            boolean persistChanged = false;
7851            GrantUri grantUri = new GrantUri(userId, uri, false);
7852
7853            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7854                    new GrantUri(userId, uri, false));
7855            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7856                    new GrantUri(userId, uri, true));
7857
7858            final boolean exactValid = (exactPerm != null)
7859                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7860            final boolean prefixValid = (prefixPerm != null)
7861                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7862
7863            if (!(exactValid || prefixValid)) {
7864                throw new SecurityException("No persistable permission grants found for UID "
7865                        + callingUid + " and Uri " + grantUri.toSafeString());
7866            }
7867
7868            if (exactValid) {
7869                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7870            }
7871            if (prefixValid) {
7872                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7873            }
7874
7875            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7876
7877            if (persistChanged) {
7878                schedulePersistUriGrants();
7879            }
7880        }
7881    }
7882
7883    /**
7884     * @param uri This uri must NOT contain an embedded userId.
7885     * @param userId The userId in which the uri is to be resolved.
7886     */
7887    @Override
7888    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7889        enforceNotIsolatedCaller("releasePersistableUriPermission");
7890
7891        Preconditions.checkFlagsArgument(modeFlags,
7892                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7893
7894        synchronized (this) {
7895            final int callingUid = Binder.getCallingUid();
7896            boolean persistChanged = false;
7897
7898            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7899                    new GrantUri(userId, uri, false));
7900            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7901                    new GrantUri(userId, uri, true));
7902            if (exactPerm == null && prefixPerm == null) {
7903                throw new SecurityException("No permission grants found for UID " + callingUid
7904                        + " and Uri " + uri.toSafeString());
7905            }
7906
7907            if (exactPerm != null) {
7908                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7909                removeUriPermissionIfNeededLocked(exactPerm);
7910            }
7911            if (prefixPerm != null) {
7912                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7913                removeUriPermissionIfNeededLocked(prefixPerm);
7914            }
7915
7916            if (persistChanged) {
7917                schedulePersistUriGrants();
7918            }
7919        }
7920    }
7921
7922    /**
7923     * Prune any older {@link UriPermission} for the given UID until outstanding
7924     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7925     *
7926     * @return if any mutations occured that require persisting.
7927     */
7928    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7929        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7930        if (perms == null) return false;
7931        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7932
7933        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7934        for (UriPermission perm : perms.values()) {
7935            if (perm.persistedModeFlags != 0) {
7936                persisted.add(perm);
7937            }
7938        }
7939
7940        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7941        if (trimCount <= 0) return false;
7942
7943        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7944        for (int i = 0; i < trimCount; i++) {
7945            final UriPermission perm = persisted.get(i);
7946
7947            if (DEBUG_URI_PERMISSION) {
7948                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7949            }
7950
7951            perm.releasePersistableModes(~0);
7952            removeUriPermissionIfNeededLocked(perm);
7953        }
7954
7955        return true;
7956    }
7957
7958    @Override
7959    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7960            String packageName, boolean incoming) {
7961        enforceNotIsolatedCaller("getPersistedUriPermissions");
7962        Preconditions.checkNotNull(packageName, "packageName");
7963
7964        final int callingUid = Binder.getCallingUid();
7965        final IPackageManager pm = AppGlobals.getPackageManager();
7966        try {
7967            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7968            if (packageUid != callingUid) {
7969                throw new SecurityException(
7970                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7971            }
7972        } catch (RemoteException e) {
7973            throw new SecurityException("Failed to verify package name ownership");
7974        }
7975
7976        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7977        synchronized (this) {
7978            if (incoming) {
7979                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7980                        callingUid);
7981                if (perms == null) {
7982                    Slog.w(TAG, "No permission grants found for " + packageName);
7983                } else {
7984                    for (UriPermission perm : perms.values()) {
7985                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7986                            result.add(perm.buildPersistedPublicApiObject());
7987                        }
7988                    }
7989                }
7990            } else {
7991                final int size = mGrantedUriPermissions.size();
7992                for (int i = 0; i < size; i++) {
7993                    final ArrayMap<GrantUri, UriPermission> perms =
7994                            mGrantedUriPermissions.valueAt(i);
7995                    for (UriPermission perm : perms.values()) {
7996                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7997                            result.add(perm.buildPersistedPublicApiObject());
7998                        }
7999                    }
8000                }
8001            }
8002        }
8003        return new ParceledListSlice<android.content.UriPermission>(result);
8004    }
8005
8006    @Override
8007    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8008        synchronized (this) {
8009            ProcessRecord app =
8010                who != null ? getRecordForAppLocked(who) : null;
8011            if (app == null) return;
8012
8013            Message msg = Message.obtain();
8014            msg.what = WAIT_FOR_DEBUGGER_MSG;
8015            msg.obj = app;
8016            msg.arg1 = waiting ? 1 : 0;
8017            mHandler.sendMessage(msg);
8018        }
8019    }
8020
8021    @Override
8022    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8023        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8024        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8025        outInfo.availMem = Process.getFreeMemory();
8026        outInfo.totalMem = Process.getTotalMemory();
8027        outInfo.threshold = homeAppMem;
8028        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8029        outInfo.hiddenAppThreshold = cachedAppMem;
8030        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8031                ProcessList.SERVICE_ADJ);
8032        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8033                ProcessList.VISIBLE_APP_ADJ);
8034        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8035                ProcessList.FOREGROUND_APP_ADJ);
8036    }
8037
8038    // =========================================================
8039    // TASK MANAGEMENT
8040    // =========================================================
8041
8042    @Override
8043    public List<IAppTask> getAppTasks(String callingPackage) {
8044        int callingUid = Binder.getCallingUid();
8045        long ident = Binder.clearCallingIdentity();
8046
8047        synchronized(this) {
8048            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8049            try {
8050                if (localLOGV) Slog.v(TAG, "getAppTasks");
8051
8052                final int N = mRecentTasks.size();
8053                for (int i = 0; i < N; i++) {
8054                    TaskRecord tr = mRecentTasks.get(i);
8055                    // Skip tasks that do not match the caller.  We don't need to verify
8056                    // callingPackage, because we are also limiting to callingUid and know
8057                    // that will limit to the correct security sandbox.
8058                    if (tr.effectiveUid != callingUid) {
8059                        continue;
8060                    }
8061                    Intent intent = tr.getBaseIntent();
8062                    if (intent == null ||
8063                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8064                        continue;
8065                    }
8066                    ActivityManager.RecentTaskInfo taskInfo =
8067                            createRecentTaskInfoFromTaskRecord(tr);
8068                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8069                    list.add(taskImpl);
8070                }
8071            } finally {
8072                Binder.restoreCallingIdentity(ident);
8073            }
8074            return list;
8075        }
8076    }
8077
8078    @Override
8079    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8080        final int callingUid = Binder.getCallingUid();
8081        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8082
8083        synchronized(this) {
8084            if (localLOGV) Slog.v(
8085                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8086
8087            final boolean allowed = checkCallingPermission(
8088                    android.Manifest.permission.GET_TASKS)
8089                    == PackageManager.PERMISSION_GRANTED;
8090            if (!allowed) {
8091                Slog.w(TAG, "getTasks: caller " + callingUid
8092                        + " does not hold GET_TASKS; limiting output");
8093            }
8094
8095            // TODO: Improve with MRU list from all ActivityStacks.
8096            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8097        }
8098
8099        return list;
8100    }
8101
8102    TaskRecord getMostRecentTask() {
8103        return mRecentTasks.get(0);
8104    }
8105
8106    /**
8107     * Creates a new RecentTaskInfo from a TaskRecord.
8108     */
8109    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8110        // Update the task description to reflect any changes in the task stack
8111        tr.updateTaskDescription();
8112
8113        // Compose the recent task info
8114        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8115        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8116        rti.persistentId = tr.taskId;
8117        rti.baseIntent = new Intent(tr.getBaseIntent());
8118        rti.origActivity = tr.origActivity;
8119        rti.description = tr.lastDescription;
8120        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8121        rti.userId = tr.userId;
8122        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8123        rti.firstActiveTime = tr.firstActiveTime;
8124        rti.lastActiveTime = tr.lastActiveTime;
8125        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8126        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8127        return rti;
8128    }
8129
8130    @Override
8131    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8132        final int callingUid = Binder.getCallingUid();
8133        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8134                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8135
8136        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8137        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8138        synchronized (this) {
8139            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8140                    == PackageManager.PERMISSION_GRANTED;
8141            if (!allowed) {
8142                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8143                        + " does not hold GET_TASKS; limiting output");
8144            }
8145            final boolean detailed = checkCallingPermission(
8146                    android.Manifest.permission.GET_DETAILED_TASKS)
8147                    == PackageManager.PERMISSION_GRANTED;
8148
8149            final int N = mRecentTasks.size();
8150            ArrayList<ActivityManager.RecentTaskInfo> res
8151                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8152                            maxNum < N ? maxNum : N);
8153
8154            final Set<Integer> includedUsers;
8155            if (includeProfiles) {
8156                includedUsers = getProfileIdsLocked(userId);
8157            } else {
8158                includedUsers = new HashSet<Integer>();
8159            }
8160            includedUsers.add(Integer.valueOf(userId));
8161
8162            for (int i=0; i<N && maxNum > 0; i++) {
8163                TaskRecord tr = mRecentTasks.get(i);
8164                // Only add calling user or related users recent tasks
8165                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8166                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8167                    continue;
8168                }
8169
8170                // Return the entry if desired by the caller.  We always return
8171                // the first entry, because callers always expect this to be the
8172                // foreground app.  We may filter others if the caller has
8173                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8174                // we should exclude the entry.
8175
8176                if (i == 0
8177                        || withExcluded
8178                        || (tr.intent == null)
8179                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8180                                == 0)) {
8181                    if (!allowed) {
8182                        // If the caller doesn't have the GET_TASKS permission, then only
8183                        // allow them to see a small subset of tasks -- their own and home.
8184                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8185                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8186                            continue;
8187                        }
8188                    }
8189                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8190                        if (tr.stack != null && tr.stack.isHomeStack()) {
8191                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8192                            continue;
8193                        }
8194                    }
8195                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8196                        // Don't include auto remove tasks that are finished or finishing.
8197                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8198                                + tr);
8199                        continue;
8200                    }
8201                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8202                            && !tr.isAvailable) {
8203                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8204                        continue;
8205                    }
8206
8207                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8208                    if (!detailed) {
8209                        rti.baseIntent.replaceExtras((Bundle)null);
8210                    }
8211
8212                    res.add(rti);
8213                    maxNum--;
8214                }
8215            }
8216            return res;
8217        }
8218    }
8219
8220    private TaskRecord recentTaskForIdLocked(int id) {
8221        final int N = mRecentTasks.size();
8222            for (int i=0; i<N; i++) {
8223                TaskRecord tr = mRecentTasks.get(i);
8224                if (tr.taskId == id) {
8225                    return tr;
8226                }
8227            }
8228            return null;
8229    }
8230
8231    @Override
8232    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8233        synchronized (this) {
8234            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8235                    "getTaskThumbnail()");
8236            TaskRecord tr = recentTaskForIdLocked(id);
8237            if (tr != null) {
8238                return tr.getTaskThumbnailLocked();
8239            }
8240        }
8241        return null;
8242    }
8243
8244    @Override
8245    public int addAppTask(IBinder activityToken, Intent intent,
8246            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8247        final int callingUid = Binder.getCallingUid();
8248        final long callingIdent = Binder.clearCallingIdentity();
8249
8250        try {
8251            synchronized (this) {
8252                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8253                if (r == null) {
8254                    throw new IllegalArgumentException("Activity does not exist; token="
8255                            + activityToken);
8256                }
8257                ComponentName comp = intent.getComponent();
8258                if (comp == null) {
8259                    throw new IllegalArgumentException("Intent " + intent
8260                            + " must specify explicit component");
8261                }
8262                if (thumbnail.getWidth() != mThumbnailWidth
8263                        || thumbnail.getHeight() != mThumbnailHeight) {
8264                    throw new IllegalArgumentException("Bad thumbnail size: got "
8265                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8266                            + mThumbnailWidth + "x" + mThumbnailHeight);
8267                }
8268                if (intent.getSelector() != null) {
8269                    intent.setSelector(null);
8270                }
8271                if (intent.getSourceBounds() != null) {
8272                    intent.setSourceBounds(null);
8273                }
8274                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8275                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8276                        // The caller has added this as an auto-remove task...  that makes no
8277                        // sense, so turn off auto-remove.
8278                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8279                    }
8280                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8281                    // Must be a new task.
8282                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8283                }
8284                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8285                    mLastAddedTaskActivity = null;
8286                }
8287                ActivityInfo ainfo = mLastAddedTaskActivity;
8288                if (ainfo == null) {
8289                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8290                            comp, 0, UserHandle.getUserId(callingUid));
8291                    if (ainfo.applicationInfo.uid != callingUid) {
8292                        throw new SecurityException(
8293                                "Can't add task for another application: target uid="
8294                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8295                    }
8296                }
8297
8298                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8299                        intent, description);
8300
8301                int trimIdx = trimRecentsForTask(task, false);
8302                if (trimIdx >= 0) {
8303                    // If this would have caused a trim, then we'll abort because that
8304                    // means it would be added at the end of the list but then just removed.
8305                    return -1;
8306                }
8307
8308                final int N = mRecentTasks.size();
8309                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8310                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8311                    tr.removedFromRecents(mTaskPersister);
8312                }
8313
8314                task.inRecents = true;
8315                mRecentTasks.add(task);
8316                r.task.stack.addTask(task, false, false);
8317
8318                task.setLastThumbnail(thumbnail);
8319                task.freeLastThumbnail();
8320
8321                return task.taskId;
8322            }
8323        } finally {
8324            Binder.restoreCallingIdentity(callingIdent);
8325        }
8326    }
8327
8328    @Override
8329    public Point getAppTaskThumbnailSize() {
8330        synchronized (this) {
8331            return new Point(mThumbnailWidth,  mThumbnailHeight);
8332        }
8333    }
8334
8335    @Override
8336    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8337        synchronized (this) {
8338            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8339            if (r != null) {
8340                r.taskDescription = td;
8341                r.task.updateTaskDescription();
8342            }
8343        }
8344    }
8345
8346    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8347        mRecentTasks.remove(tr);
8348        tr.removedFromRecents(mTaskPersister);
8349        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8350        Intent baseIntent = new Intent(
8351                tr.intent != null ? tr.intent : tr.affinityIntent);
8352        ComponentName component = baseIntent.getComponent();
8353        if (component == null) {
8354            Slog.w(TAG, "Now component for base intent of task: " + tr);
8355            return;
8356        }
8357
8358        // Find any running services associated with this app.
8359        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8360
8361        if (killProcesses) {
8362            // Find any running processes associated with this app.
8363            final String pkg = component.getPackageName();
8364            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8365            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8366            for (int i=0; i<pmap.size(); i++) {
8367                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8368                for (int j=0; j<uids.size(); j++) {
8369                    ProcessRecord proc = uids.valueAt(j);
8370                    if (proc.userId != tr.userId) {
8371                        continue;
8372                    }
8373                    if (!proc.pkgList.containsKey(pkg)) {
8374                        continue;
8375                    }
8376                    procs.add(proc);
8377                }
8378            }
8379
8380            // Kill the running processes.
8381            for (int i=0; i<procs.size(); i++) {
8382                ProcessRecord pr = procs.get(i);
8383                if (pr == mHomeProcess) {
8384                    // Don't kill the home process along with tasks from the same package.
8385                    continue;
8386                }
8387                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8388                    pr.kill("remove task", true);
8389                } else {
8390                    pr.waitingToKill = "remove task";
8391                }
8392            }
8393        }
8394    }
8395
8396    /**
8397     * Removes the task with the specified task id.
8398     *
8399     * @param taskId Identifier of the task to be removed.
8400     * @param flags Additional operational flags.  May be 0 or
8401     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8402     * @return Returns true if the given task was found and removed.
8403     */
8404    private boolean removeTaskByIdLocked(int taskId, int flags) {
8405        TaskRecord tr = recentTaskForIdLocked(taskId);
8406        if (tr != null) {
8407            tr.removeTaskActivitiesLocked();
8408            cleanUpRemovedTaskLocked(tr, flags);
8409            if (tr.isPersistable) {
8410                notifyTaskPersisterLocked(null, true);
8411            }
8412            return true;
8413        }
8414        return false;
8415    }
8416
8417    @Override
8418    public boolean removeTask(int taskId, int flags) {
8419        synchronized (this) {
8420            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8421                    "removeTask()");
8422            long ident = Binder.clearCallingIdentity();
8423            try {
8424                return removeTaskByIdLocked(taskId, flags);
8425            } finally {
8426                Binder.restoreCallingIdentity(ident);
8427            }
8428        }
8429    }
8430
8431    /**
8432     * TODO: Add mController hook
8433     */
8434    @Override
8435    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8436        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8437                "moveTaskToFront()");
8438
8439        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8440        synchronized(this) {
8441            moveTaskToFrontLocked(taskId, flags, options);
8442        }
8443    }
8444
8445    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8446        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8447                Binder.getCallingUid(), "Task to front")) {
8448            ActivityOptions.abort(options);
8449            return;
8450        }
8451        final long origId = Binder.clearCallingIdentity();
8452        try {
8453            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8454            if (task == null) {
8455                return;
8456            }
8457            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8458                mStackSupervisor.showLockTaskToast();
8459                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8460                return;
8461            }
8462            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8463            if (prev != null && prev.isRecentsActivity()) {
8464                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8465            }
8466            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8467        } finally {
8468            Binder.restoreCallingIdentity(origId);
8469        }
8470        ActivityOptions.abort(options);
8471    }
8472
8473    @Override
8474    public void moveTaskToBack(int taskId) {
8475        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8476                "moveTaskToBack()");
8477
8478        synchronized(this) {
8479            TaskRecord tr = recentTaskForIdLocked(taskId);
8480            if (tr != null) {
8481                if (tr == mStackSupervisor.mLockTaskModeTask) {
8482                    mStackSupervisor.showLockTaskToast();
8483                    return;
8484                }
8485                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8486                ActivityStack stack = tr.stack;
8487                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8488                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8489                            Binder.getCallingUid(), "Task to back")) {
8490                        return;
8491                    }
8492                }
8493                final long origId = Binder.clearCallingIdentity();
8494                try {
8495                    stack.moveTaskToBackLocked(taskId, null);
8496                } finally {
8497                    Binder.restoreCallingIdentity(origId);
8498                }
8499            }
8500        }
8501    }
8502
8503    /**
8504     * Moves an activity, and all of the other activities within the same task, to the bottom
8505     * of the history stack.  The activity's order within the task is unchanged.
8506     *
8507     * @param token A reference to the activity we wish to move
8508     * @param nonRoot If false then this only works if the activity is the root
8509     *                of a task; if true it will work for any activity in a task.
8510     * @return Returns true if the move completed, false if not.
8511     */
8512    @Override
8513    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8514        enforceNotIsolatedCaller("moveActivityTaskToBack");
8515        synchronized(this) {
8516            final long origId = Binder.clearCallingIdentity();
8517            try {
8518                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8519                if (taskId >= 0) {
8520                    if ((mStackSupervisor.mLockTaskModeTask != null)
8521                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8522                        mStackSupervisor.showLockTaskToast();
8523                        return false;
8524                    }
8525                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8526                }
8527            } finally {
8528                Binder.restoreCallingIdentity(origId);
8529            }
8530        }
8531        return false;
8532    }
8533
8534    @Override
8535    public void moveTaskBackwards(int task) {
8536        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8537                "moveTaskBackwards()");
8538
8539        synchronized(this) {
8540            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8541                    Binder.getCallingUid(), "Task backwards")) {
8542                return;
8543            }
8544            final long origId = Binder.clearCallingIdentity();
8545            moveTaskBackwardsLocked(task);
8546            Binder.restoreCallingIdentity(origId);
8547        }
8548    }
8549
8550    private final void moveTaskBackwardsLocked(int task) {
8551        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8552    }
8553
8554    @Override
8555    public IBinder getHomeActivityToken() throws RemoteException {
8556        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8557                "getHomeActivityToken()");
8558        synchronized (this) {
8559            return mStackSupervisor.getHomeActivityToken();
8560        }
8561    }
8562
8563    @Override
8564    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8565            IActivityContainerCallback callback) throws RemoteException {
8566        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8567                "createActivityContainer()");
8568        synchronized (this) {
8569            if (parentActivityToken == null) {
8570                throw new IllegalArgumentException("parent token must not be null");
8571            }
8572            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8573            if (r == null) {
8574                return null;
8575            }
8576            if (callback == null) {
8577                throw new IllegalArgumentException("callback must not be null");
8578            }
8579            return mStackSupervisor.createActivityContainer(r, callback);
8580        }
8581    }
8582
8583    @Override
8584    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8585        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8586                "deleteActivityContainer()");
8587        synchronized (this) {
8588            mStackSupervisor.deleteActivityContainer(container);
8589        }
8590    }
8591
8592    @Override
8593    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8594            throws RemoteException {
8595        synchronized (this) {
8596            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8597            if (stack != null) {
8598                return stack.mActivityContainer;
8599            }
8600            return null;
8601        }
8602    }
8603
8604    @Override
8605    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8607                "moveTaskToStack()");
8608        if (stackId == HOME_STACK_ID) {
8609            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8610                    new RuntimeException("here").fillInStackTrace());
8611        }
8612        synchronized (this) {
8613            long ident = Binder.clearCallingIdentity();
8614            try {
8615                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8616                        + stackId + " toTop=" + toTop);
8617                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8618            } finally {
8619                Binder.restoreCallingIdentity(ident);
8620            }
8621        }
8622    }
8623
8624    @Override
8625    public void resizeStack(int stackBoxId, Rect bounds) {
8626        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8627                "resizeStackBox()");
8628        long ident = Binder.clearCallingIdentity();
8629        try {
8630            mWindowManager.resizeStack(stackBoxId, bounds);
8631        } finally {
8632            Binder.restoreCallingIdentity(ident);
8633        }
8634    }
8635
8636    @Override
8637    public List<StackInfo> getAllStackInfos() {
8638        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8639                "getAllStackInfos()");
8640        long ident = Binder.clearCallingIdentity();
8641        try {
8642            synchronized (this) {
8643                return mStackSupervisor.getAllStackInfosLocked();
8644            }
8645        } finally {
8646            Binder.restoreCallingIdentity(ident);
8647        }
8648    }
8649
8650    @Override
8651    public StackInfo getStackInfo(int stackId) {
8652        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8653                "getStackInfo()");
8654        long ident = Binder.clearCallingIdentity();
8655        try {
8656            synchronized (this) {
8657                return mStackSupervisor.getStackInfoLocked(stackId);
8658            }
8659        } finally {
8660            Binder.restoreCallingIdentity(ident);
8661        }
8662    }
8663
8664    @Override
8665    public boolean isInHomeStack(int taskId) {
8666        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8667                "getStackInfo()");
8668        long ident = Binder.clearCallingIdentity();
8669        try {
8670            synchronized (this) {
8671                TaskRecord tr = recentTaskForIdLocked(taskId);
8672                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8673            }
8674        } finally {
8675            Binder.restoreCallingIdentity(ident);
8676        }
8677    }
8678
8679    @Override
8680    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8681        synchronized(this) {
8682            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8683        }
8684    }
8685
8686    private boolean isLockTaskAuthorized(String pkg) {
8687        final DevicePolicyManager dpm = (DevicePolicyManager)
8688                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8689        try {
8690            int uid = mContext.getPackageManager().getPackageUid(pkg,
8691                    Binder.getCallingUserHandle().getIdentifier());
8692            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8693        } catch (NameNotFoundException e) {
8694            return false;
8695        }
8696    }
8697
8698    void startLockTaskMode(TaskRecord task) {
8699        final String pkg;
8700        synchronized (this) {
8701            pkg = task.intent.getComponent().getPackageName();
8702        }
8703        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8704        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8705            final TaskRecord taskRecord = task;
8706            mHandler.post(new Runnable() {
8707                @Override
8708                public void run() {
8709                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8710                }
8711            });
8712            return;
8713        }
8714        long ident = Binder.clearCallingIdentity();
8715        try {
8716            synchronized (this) {
8717                // Since we lost lock on task, make sure it is still there.
8718                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8719                if (task != null) {
8720                    if (!isSystemInitiated
8721                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8722                        throw new IllegalArgumentException("Invalid task, not in foreground");
8723                    }
8724                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8725                }
8726            }
8727        } finally {
8728            Binder.restoreCallingIdentity(ident);
8729        }
8730    }
8731
8732    @Override
8733    public void startLockTaskMode(int taskId) {
8734        final TaskRecord task;
8735        long ident = Binder.clearCallingIdentity();
8736        try {
8737            synchronized (this) {
8738                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8739            }
8740        } finally {
8741            Binder.restoreCallingIdentity(ident);
8742        }
8743        if (task != null) {
8744            startLockTaskMode(task);
8745        }
8746    }
8747
8748    @Override
8749    public void startLockTaskMode(IBinder token) {
8750        final TaskRecord task;
8751        long ident = Binder.clearCallingIdentity();
8752        try {
8753            synchronized (this) {
8754                final ActivityRecord r = ActivityRecord.forToken(token);
8755                if (r == null) {
8756                    return;
8757                }
8758                task = r.task;
8759            }
8760        } finally {
8761            Binder.restoreCallingIdentity(ident);
8762        }
8763        if (task != null) {
8764            startLockTaskMode(task);
8765        }
8766    }
8767
8768    @Override
8769    public void startLockTaskModeOnCurrent() throws RemoteException {
8770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8771                "startLockTaskModeOnCurrent");
8772        ActivityRecord r = null;
8773        synchronized (this) {
8774            r = mStackSupervisor.topRunningActivityLocked();
8775        }
8776        startLockTaskMode(r.task);
8777    }
8778
8779    @Override
8780    public void stopLockTaskMode() {
8781        // Verify that the user matches the package of the intent for the TaskRecord
8782        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8783        // and stopLockTaskMode.
8784        final int callingUid = Binder.getCallingUid();
8785        if (callingUid != Process.SYSTEM_UID) {
8786            try {
8787                String pkg =
8788                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8789                int uid = mContext.getPackageManager().getPackageUid(pkg,
8790                        Binder.getCallingUserHandle().getIdentifier());
8791                if (uid != callingUid) {
8792                    throw new SecurityException("Invalid uid, expected " + uid);
8793                }
8794            } catch (NameNotFoundException e) {
8795                Log.d(TAG, "stopLockTaskMode " + e);
8796                return;
8797            }
8798        }
8799        long ident = Binder.clearCallingIdentity();
8800        try {
8801            Log.d(TAG, "stopLockTaskMode");
8802            // Stop lock task
8803            synchronized (this) {
8804                mStackSupervisor.setLockTaskModeLocked(null, false);
8805            }
8806        } finally {
8807            Binder.restoreCallingIdentity(ident);
8808        }
8809    }
8810
8811    @Override
8812    public void stopLockTaskModeOnCurrent() throws RemoteException {
8813        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8814                "stopLockTaskModeOnCurrent");
8815        long ident = Binder.clearCallingIdentity();
8816        try {
8817            stopLockTaskMode();
8818        } finally {
8819            Binder.restoreCallingIdentity(ident);
8820        }
8821    }
8822
8823    @Override
8824    public boolean isInLockTaskMode() {
8825        synchronized (this) {
8826            return mStackSupervisor.isInLockTaskMode();
8827        }
8828    }
8829
8830    // =========================================================
8831    // CONTENT PROVIDERS
8832    // =========================================================
8833
8834    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8835        List<ProviderInfo> providers = null;
8836        try {
8837            providers = AppGlobals.getPackageManager().
8838                queryContentProviders(app.processName, app.uid,
8839                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8840        } catch (RemoteException ex) {
8841        }
8842        if (DEBUG_MU)
8843            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8844        int userId = app.userId;
8845        if (providers != null) {
8846            int N = providers.size();
8847            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8848            for (int i=0; i<N; i++) {
8849                ProviderInfo cpi =
8850                    (ProviderInfo)providers.get(i);
8851                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8852                        cpi.name, cpi.flags);
8853                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8854                    // This is a singleton provider, but a user besides the
8855                    // default user is asking to initialize a process it runs
8856                    // in...  well, no, it doesn't actually run in this process,
8857                    // it runs in the process of the default user.  Get rid of it.
8858                    providers.remove(i);
8859                    N--;
8860                    i--;
8861                    continue;
8862                }
8863
8864                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8865                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8866                if (cpr == null) {
8867                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8868                    mProviderMap.putProviderByClass(comp, cpr);
8869                }
8870                if (DEBUG_MU)
8871                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8872                app.pubProviders.put(cpi.name, cpr);
8873                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8874                    // Don't add this if it is a platform component that is marked
8875                    // to run in multiple processes, because this is actually
8876                    // part of the framework so doesn't make sense to track as a
8877                    // separate apk in the process.
8878                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8879                            mProcessStats);
8880                }
8881                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8882            }
8883        }
8884        return providers;
8885    }
8886
8887    /**
8888     * Check if {@link ProcessRecord} has a possible chance at accessing the
8889     * given {@link ProviderInfo}. Final permission checking is always done
8890     * in {@link ContentProvider}.
8891     */
8892    private final String checkContentProviderPermissionLocked(
8893            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8894        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8895        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8896        boolean checkedGrants = false;
8897        if (checkUser) {
8898            // Looking for cross-user grants before enforcing the typical cross-users permissions
8899            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8900            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8901                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8902                    return null;
8903                }
8904                checkedGrants = true;
8905            }
8906            userId = handleIncomingUser(callingPid, callingUid, userId,
8907                    false, ALLOW_NON_FULL,
8908                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8909            if (userId != tmpTargetUserId) {
8910                // When we actually went to determine the final targer user ID, this ended
8911                // up different than our initial check for the authority.  This is because
8912                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8913                // SELF.  So we need to re-check the grants again.
8914                checkedGrants = false;
8915            }
8916        }
8917        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8918                cpi.applicationInfo.uid, cpi.exported)
8919                == PackageManager.PERMISSION_GRANTED) {
8920            return null;
8921        }
8922        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8923                cpi.applicationInfo.uid, cpi.exported)
8924                == PackageManager.PERMISSION_GRANTED) {
8925            return null;
8926        }
8927
8928        PathPermission[] pps = cpi.pathPermissions;
8929        if (pps != null) {
8930            int i = pps.length;
8931            while (i > 0) {
8932                i--;
8933                PathPermission pp = pps[i];
8934                String pprperm = pp.getReadPermission();
8935                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8936                        cpi.applicationInfo.uid, cpi.exported)
8937                        == PackageManager.PERMISSION_GRANTED) {
8938                    return null;
8939                }
8940                String ppwperm = pp.getWritePermission();
8941                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8942                        cpi.applicationInfo.uid, cpi.exported)
8943                        == PackageManager.PERMISSION_GRANTED) {
8944                    return null;
8945                }
8946            }
8947        }
8948        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8949            return null;
8950        }
8951
8952        String msg;
8953        if (!cpi.exported) {
8954            msg = "Permission Denial: opening provider " + cpi.name
8955                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8956                    + ", uid=" + callingUid + ") that is not exported from uid "
8957                    + cpi.applicationInfo.uid;
8958        } else {
8959            msg = "Permission Denial: opening provider " + cpi.name
8960                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8961                    + ", uid=" + callingUid + ") requires "
8962                    + cpi.readPermission + " or " + cpi.writePermission;
8963        }
8964        Slog.w(TAG, msg);
8965        return msg;
8966    }
8967
8968    /**
8969     * Returns if the ContentProvider has granted a uri to callingUid
8970     */
8971    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8972        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8973        if (perms != null) {
8974            for (int i=perms.size()-1; i>=0; i--) {
8975                GrantUri grantUri = perms.keyAt(i);
8976                if (grantUri.sourceUserId == userId || !checkUser) {
8977                    if (matchesProvider(grantUri.uri, cpi)) {
8978                        return true;
8979                    }
8980                }
8981            }
8982        }
8983        return false;
8984    }
8985
8986    /**
8987     * Returns true if the uri authority is one of the authorities specified in the provider.
8988     */
8989    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8990        String uriAuth = uri.getAuthority();
8991        String cpiAuth = cpi.authority;
8992        if (cpiAuth.indexOf(';') == -1) {
8993            return cpiAuth.equals(uriAuth);
8994        }
8995        String[] cpiAuths = cpiAuth.split(";");
8996        int length = cpiAuths.length;
8997        for (int i = 0; i < length; i++) {
8998            if (cpiAuths[i].equals(uriAuth)) return true;
8999        }
9000        return false;
9001    }
9002
9003    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9004            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9005        if (r != null) {
9006            for (int i=0; i<r.conProviders.size(); i++) {
9007                ContentProviderConnection conn = r.conProviders.get(i);
9008                if (conn.provider == cpr) {
9009                    if (DEBUG_PROVIDER) Slog.v(TAG,
9010                            "Adding provider requested by "
9011                            + r.processName + " from process "
9012                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9013                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9014                    if (stable) {
9015                        conn.stableCount++;
9016                        conn.numStableIncs++;
9017                    } else {
9018                        conn.unstableCount++;
9019                        conn.numUnstableIncs++;
9020                    }
9021                    return conn;
9022                }
9023            }
9024            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9025            if (stable) {
9026                conn.stableCount = 1;
9027                conn.numStableIncs = 1;
9028            } else {
9029                conn.unstableCount = 1;
9030                conn.numUnstableIncs = 1;
9031            }
9032            cpr.connections.add(conn);
9033            r.conProviders.add(conn);
9034            return conn;
9035        }
9036        cpr.addExternalProcessHandleLocked(externalProcessToken);
9037        return null;
9038    }
9039
9040    boolean decProviderCountLocked(ContentProviderConnection conn,
9041            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9042        if (conn != null) {
9043            cpr = conn.provider;
9044            if (DEBUG_PROVIDER) Slog.v(TAG,
9045                    "Removing provider requested by "
9046                    + conn.client.processName + " from process "
9047                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9048                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9049            if (stable) {
9050                conn.stableCount--;
9051            } else {
9052                conn.unstableCount--;
9053            }
9054            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9055                cpr.connections.remove(conn);
9056                conn.client.conProviders.remove(conn);
9057                return true;
9058            }
9059            return false;
9060        }
9061        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9062        return false;
9063    }
9064
9065    private void checkTime(long startTime, String where) {
9066        long now = SystemClock.elapsedRealtime();
9067        if ((now-startTime) > 1000) {
9068            // If we are taking more than a second, log about it.
9069            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9070        }
9071    }
9072
9073    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9074            String name, IBinder token, boolean stable, int userId) {
9075        ContentProviderRecord cpr;
9076        ContentProviderConnection conn = null;
9077        ProviderInfo cpi = null;
9078
9079        synchronized(this) {
9080            long startTime = SystemClock.elapsedRealtime();
9081
9082            ProcessRecord r = null;
9083            if (caller != null) {
9084                r = getRecordForAppLocked(caller);
9085                if (r == null) {
9086                    throw new SecurityException(
9087                            "Unable to find app for caller " + caller
9088                          + " (pid=" + Binder.getCallingPid()
9089                          + ") when getting content provider " + name);
9090                }
9091            }
9092
9093            boolean checkCrossUser = true;
9094
9095            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9096
9097            // First check if this content provider has been published...
9098            cpr = mProviderMap.getProviderByName(name, userId);
9099            // If that didn't work, check if it exists for user 0 and then
9100            // verify that it's a singleton provider before using it.
9101            if (cpr == null && userId != UserHandle.USER_OWNER) {
9102                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9103                if (cpr != null) {
9104                    cpi = cpr.info;
9105                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9106                            cpi.name, cpi.flags)
9107                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9108                        userId = UserHandle.USER_OWNER;
9109                        checkCrossUser = false;
9110                    } else {
9111                        cpr = null;
9112                        cpi = null;
9113                    }
9114                }
9115            }
9116
9117            boolean providerRunning = cpr != null;
9118            if (providerRunning) {
9119                cpi = cpr.info;
9120                String msg;
9121                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9122                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9123                        != null) {
9124                    throw new SecurityException(msg);
9125                }
9126                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9127
9128                if (r != null && cpr.canRunHere(r)) {
9129                    // This provider has been published or is in the process
9130                    // of being published...  but it is also allowed to run
9131                    // in the caller's process, so don't make a connection
9132                    // and just let the caller instantiate its own instance.
9133                    ContentProviderHolder holder = cpr.newHolder(null);
9134                    // don't give caller the provider object, it needs
9135                    // to make its own.
9136                    holder.provider = null;
9137                    return holder;
9138                }
9139
9140                final long origId = Binder.clearCallingIdentity();
9141
9142                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9143
9144                // In this case the provider instance already exists, so we can
9145                // return it right away.
9146                conn = incProviderCountLocked(r, cpr, token, stable);
9147                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9148                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9149                        // If this is a perceptible app accessing the provider,
9150                        // make sure to count it as being accessed and thus
9151                        // back up on the LRU list.  This is good because
9152                        // content providers are often expensive to start.
9153                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9154                        updateLruProcessLocked(cpr.proc, false, null);
9155                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9156                    }
9157                }
9158
9159                if (cpr.proc != null) {
9160                    if (false) {
9161                        if (cpr.name.flattenToShortString().equals(
9162                                "com.android.providers.calendar/.CalendarProvider2")) {
9163                            Slog.v(TAG, "****************** KILLING "
9164                                + cpr.name.flattenToShortString());
9165                            Process.killProcess(cpr.proc.pid);
9166                        }
9167                    }
9168                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9169                    boolean success = updateOomAdjLocked(cpr.proc);
9170                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9171                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9172                    // NOTE: there is still a race here where a signal could be
9173                    // pending on the process even though we managed to update its
9174                    // adj level.  Not sure what to do about this, but at least
9175                    // the race is now smaller.
9176                    if (!success) {
9177                        // Uh oh...  it looks like the provider's process
9178                        // has been killed on us.  We need to wait for a new
9179                        // process to be started, and make sure its death
9180                        // doesn't kill our process.
9181                        Slog.i(TAG,
9182                                "Existing provider " + cpr.name.flattenToShortString()
9183                                + " is crashing; detaching " + r);
9184                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9185                        checkTime(startTime, "getContentProviderImpl: before appDied");
9186                        appDiedLocked(cpr.proc);
9187                        checkTime(startTime, "getContentProviderImpl: after appDied");
9188                        if (!lastRef) {
9189                            // This wasn't the last ref our process had on
9190                            // the provider...  we have now been killed, bail.
9191                            return null;
9192                        }
9193                        providerRunning = false;
9194                        conn = null;
9195                    }
9196                }
9197
9198                Binder.restoreCallingIdentity(origId);
9199            }
9200
9201            boolean singleton;
9202            if (!providerRunning) {
9203                try {
9204                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9205                    cpi = AppGlobals.getPackageManager().
9206                        resolveContentProvider(name,
9207                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9208                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9209                } catch (RemoteException ex) {
9210                }
9211                if (cpi == null) {
9212                    return null;
9213                }
9214                // If the provider is a singleton AND
9215                // (it's a call within the same user || the provider is a
9216                // privileged app)
9217                // Then allow connecting to the singleton provider
9218                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9219                        cpi.name, cpi.flags)
9220                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9221                if (singleton) {
9222                    userId = UserHandle.USER_OWNER;
9223                }
9224                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9225                checkTime(startTime, "getContentProviderImpl: got app info for user");
9226
9227                String msg;
9228                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9229                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9230                        != null) {
9231                    throw new SecurityException(msg);
9232                }
9233                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9234
9235                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9236                        && !cpi.processName.equals("system")) {
9237                    // If this content provider does not run in the system
9238                    // process, and the system is not yet ready to run other
9239                    // processes, then fail fast instead of hanging.
9240                    throw new IllegalArgumentException(
9241                            "Attempt to launch content provider before system ready");
9242                }
9243
9244                // Make sure that the user who owns this provider is started.  If not,
9245                // we don't want to allow it to run.
9246                if (mStartedUsers.get(userId) == null) {
9247                    Slog.w(TAG, "Unable to launch app "
9248                            + cpi.applicationInfo.packageName + "/"
9249                            + cpi.applicationInfo.uid + " for provider "
9250                            + name + ": user " + userId + " is stopped");
9251                    return null;
9252                }
9253
9254                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9255                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9256                cpr = mProviderMap.getProviderByClass(comp, userId);
9257                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9258                final boolean firstClass = cpr == null;
9259                if (firstClass) {
9260                    try {
9261                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9262                        ApplicationInfo ai =
9263                            AppGlobals.getPackageManager().
9264                                getApplicationInfo(
9265                                        cpi.applicationInfo.packageName,
9266                                        STOCK_PM_FLAGS, userId);
9267                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9268                        if (ai == null) {
9269                            Slog.w(TAG, "No package info for content provider "
9270                                    + cpi.name);
9271                            return null;
9272                        }
9273                        ai = getAppInfoForUser(ai, userId);
9274                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9275                    } catch (RemoteException ex) {
9276                        // pm is in same process, this will never happen.
9277                    }
9278                }
9279
9280                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9281
9282                if (r != null && cpr.canRunHere(r)) {
9283                    // If this is a multiprocess provider, then just return its
9284                    // info and allow the caller to instantiate it.  Only do
9285                    // this if the provider is the same user as the caller's
9286                    // process, or can run as root (so can be in any process).
9287                    return cpr.newHolder(null);
9288                }
9289
9290                if (DEBUG_PROVIDER) {
9291                    RuntimeException e = new RuntimeException("here");
9292                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9293                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9294                }
9295
9296                // This is single process, and our app is now connecting to it.
9297                // See if we are already in the process of launching this
9298                // provider.
9299                final int N = mLaunchingProviders.size();
9300                int i;
9301                for (i=0; i<N; i++) {
9302                    if (mLaunchingProviders.get(i) == cpr) {
9303                        break;
9304                    }
9305                }
9306
9307                // If the provider is not already being launched, then get it
9308                // started.
9309                if (i >= N) {
9310                    final long origId = Binder.clearCallingIdentity();
9311
9312                    try {
9313                        // Content provider is now in use, its package can't be stopped.
9314                        try {
9315                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9316                            AppGlobals.getPackageManager().setPackageStoppedState(
9317                                    cpr.appInfo.packageName, false, userId);
9318                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9319                        } catch (RemoteException e) {
9320                        } catch (IllegalArgumentException e) {
9321                            Slog.w(TAG, "Failed trying to unstop package "
9322                                    + cpr.appInfo.packageName + ": " + e);
9323                        }
9324
9325                        // Use existing process if already started
9326                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9327                        ProcessRecord proc = getProcessRecordLocked(
9328                                cpi.processName, cpr.appInfo.uid, false);
9329                        if (proc != null && proc.thread != null) {
9330                            if (DEBUG_PROVIDER) {
9331                                Slog.d(TAG, "Installing in existing process " + proc);
9332                            }
9333                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9334                            proc.pubProviders.put(cpi.name, cpr);
9335                            try {
9336                                proc.thread.scheduleInstallProvider(cpi);
9337                            } catch (RemoteException e) {
9338                            }
9339                        } else {
9340                            checkTime(startTime, "getContentProviderImpl: before start process");
9341                            proc = startProcessLocked(cpi.processName,
9342                                    cpr.appInfo, false, 0, "content provider",
9343                                    new ComponentName(cpi.applicationInfo.packageName,
9344                                            cpi.name), false, false, false);
9345                            checkTime(startTime, "getContentProviderImpl: after start process");
9346                            if (proc == null) {
9347                                Slog.w(TAG, "Unable to launch app "
9348                                        + cpi.applicationInfo.packageName + "/"
9349                                        + cpi.applicationInfo.uid + " for provider "
9350                                        + name + ": process is bad");
9351                                return null;
9352                            }
9353                        }
9354                        cpr.launchingApp = proc;
9355                        mLaunchingProviders.add(cpr);
9356                    } finally {
9357                        Binder.restoreCallingIdentity(origId);
9358                    }
9359                }
9360
9361                checkTime(startTime, "getContentProviderImpl: updating data structures");
9362
9363                // Make sure the provider is published (the same provider class
9364                // may be published under multiple names).
9365                if (firstClass) {
9366                    mProviderMap.putProviderByClass(comp, cpr);
9367                }
9368
9369                mProviderMap.putProviderByName(name, cpr);
9370                conn = incProviderCountLocked(r, cpr, token, stable);
9371                if (conn != null) {
9372                    conn.waiting = true;
9373                }
9374            }
9375            checkTime(startTime, "getContentProviderImpl: done!");
9376        }
9377
9378        // Wait for the provider to be published...
9379        synchronized (cpr) {
9380            while (cpr.provider == null) {
9381                if (cpr.launchingApp == null) {
9382                    Slog.w(TAG, "Unable to launch app "
9383                            + cpi.applicationInfo.packageName + "/"
9384                            + cpi.applicationInfo.uid + " for provider "
9385                            + name + ": launching app became null");
9386                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9387                            UserHandle.getUserId(cpi.applicationInfo.uid),
9388                            cpi.applicationInfo.packageName,
9389                            cpi.applicationInfo.uid, name);
9390                    return null;
9391                }
9392                try {
9393                    if (DEBUG_MU) {
9394                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9395                                + cpr.launchingApp);
9396                    }
9397                    if (conn != null) {
9398                        conn.waiting = true;
9399                    }
9400                    cpr.wait();
9401                } catch (InterruptedException ex) {
9402                } finally {
9403                    if (conn != null) {
9404                        conn.waiting = false;
9405                    }
9406                }
9407            }
9408        }
9409        return cpr != null ? cpr.newHolder(conn) : null;
9410    }
9411
9412    @Override
9413    public final ContentProviderHolder getContentProvider(
9414            IApplicationThread caller, String name, int userId, boolean stable) {
9415        enforceNotIsolatedCaller("getContentProvider");
9416        if (caller == null) {
9417            String msg = "null IApplicationThread when getting content provider "
9418                    + name;
9419            Slog.w(TAG, msg);
9420            throw new SecurityException(msg);
9421        }
9422        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9423        // with cross-user grant.
9424        return getContentProviderImpl(caller, name, null, stable, userId);
9425    }
9426
9427    public ContentProviderHolder getContentProviderExternal(
9428            String name, int userId, IBinder token) {
9429        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9430            "Do not have permission in call getContentProviderExternal()");
9431        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9432                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9433        return getContentProviderExternalUnchecked(name, token, userId);
9434    }
9435
9436    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9437            IBinder token, int userId) {
9438        return getContentProviderImpl(null, name, token, true, userId);
9439    }
9440
9441    /**
9442     * Drop a content provider from a ProcessRecord's bookkeeping
9443     */
9444    public void removeContentProvider(IBinder connection, boolean stable) {
9445        enforceNotIsolatedCaller("removeContentProvider");
9446        long ident = Binder.clearCallingIdentity();
9447        try {
9448            synchronized (this) {
9449                ContentProviderConnection conn;
9450                try {
9451                    conn = (ContentProviderConnection)connection;
9452                } catch (ClassCastException e) {
9453                    String msg ="removeContentProvider: " + connection
9454                            + " not a ContentProviderConnection";
9455                    Slog.w(TAG, msg);
9456                    throw new IllegalArgumentException(msg);
9457                }
9458                if (conn == null) {
9459                    throw new NullPointerException("connection is null");
9460                }
9461                if (decProviderCountLocked(conn, null, null, stable)) {
9462                    updateOomAdjLocked();
9463                }
9464            }
9465        } finally {
9466            Binder.restoreCallingIdentity(ident);
9467        }
9468    }
9469
9470    public void removeContentProviderExternal(String name, IBinder token) {
9471        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9472            "Do not have permission in call removeContentProviderExternal()");
9473        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9474    }
9475
9476    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9477        synchronized (this) {
9478            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9479            if(cpr == null) {
9480                //remove from mProvidersByClass
9481                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9482                return;
9483            }
9484
9485            //update content provider record entry info
9486            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9487            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9488            if (localCpr.hasExternalProcessHandles()) {
9489                if (localCpr.removeExternalProcessHandleLocked(token)) {
9490                    updateOomAdjLocked();
9491                } else {
9492                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9493                            + " with no external reference for token: "
9494                            + token + ".");
9495                }
9496            } else {
9497                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9498                        + " with no external references.");
9499            }
9500        }
9501    }
9502
9503    public final void publishContentProviders(IApplicationThread caller,
9504            List<ContentProviderHolder> providers) {
9505        if (providers == null) {
9506            return;
9507        }
9508
9509        enforceNotIsolatedCaller("publishContentProviders");
9510        synchronized (this) {
9511            final ProcessRecord r = getRecordForAppLocked(caller);
9512            if (DEBUG_MU)
9513                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9514            if (r == null) {
9515                throw new SecurityException(
9516                        "Unable to find app for caller " + caller
9517                      + " (pid=" + Binder.getCallingPid()
9518                      + ") when publishing content providers");
9519            }
9520
9521            final long origId = Binder.clearCallingIdentity();
9522
9523            final int N = providers.size();
9524            for (int i=0; i<N; i++) {
9525                ContentProviderHolder src = providers.get(i);
9526                if (src == null || src.info == null || src.provider == null) {
9527                    continue;
9528                }
9529                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9530                if (DEBUG_MU)
9531                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9532                if (dst != null) {
9533                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9534                    mProviderMap.putProviderByClass(comp, dst);
9535                    String names[] = dst.info.authority.split(";");
9536                    for (int j = 0; j < names.length; j++) {
9537                        mProviderMap.putProviderByName(names[j], dst);
9538                    }
9539
9540                    int NL = mLaunchingProviders.size();
9541                    int j;
9542                    for (j=0; j<NL; j++) {
9543                        if (mLaunchingProviders.get(j) == dst) {
9544                            mLaunchingProviders.remove(j);
9545                            j--;
9546                            NL--;
9547                        }
9548                    }
9549                    synchronized (dst) {
9550                        dst.provider = src.provider;
9551                        dst.proc = r;
9552                        dst.notifyAll();
9553                    }
9554                    updateOomAdjLocked(r);
9555                }
9556            }
9557
9558            Binder.restoreCallingIdentity(origId);
9559        }
9560    }
9561
9562    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9563        ContentProviderConnection conn;
9564        try {
9565            conn = (ContentProviderConnection)connection;
9566        } catch (ClassCastException e) {
9567            String msg ="refContentProvider: " + connection
9568                    + " not a ContentProviderConnection";
9569            Slog.w(TAG, msg);
9570            throw new IllegalArgumentException(msg);
9571        }
9572        if (conn == null) {
9573            throw new NullPointerException("connection is null");
9574        }
9575
9576        synchronized (this) {
9577            if (stable > 0) {
9578                conn.numStableIncs += stable;
9579            }
9580            stable = conn.stableCount + stable;
9581            if (stable < 0) {
9582                throw new IllegalStateException("stableCount < 0: " + stable);
9583            }
9584
9585            if (unstable > 0) {
9586                conn.numUnstableIncs += unstable;
9587            }
9588            unstable = conn.unstableCount + unstable;
9589            if (unstable < 0) {
9590                throw new IllegalStateException("unstableCount < 0: " + unstable);
9591            }
9592
9593            if ((stable+unstable) <= 0) {
9594                throw new IllegalStateException("ref counts can't go to zero here: stable="
9595                        + stable + " unstable=" + unstable);
9596            }
9597            conn.stableCount = stable;
9598            conn.unstableCount = unstable;
9599            return !conn.dead;
9600        }
9601    }
9602
9603    public void unstableProviderDied(IBinder connection) {
9604        ContentProviderConnection conn;
9605        try {
9606            conn = (ContentProviderConnection)connection;
9607        } catch (ClassCastException e) {
9608            String msg ="refContentProvider: " + connection
9609                    + " not a ContentProviderConnection";
9610            Slog.w(TAG, msg);
9611            throw new IllegalArgumentException(msg);
9612        }
9613        if (conn == null) {
9614            throw new NullPointerException("connection is null");
9615        }
9616
9617        // Safely retrieve the content provider associated with the connection.
9618        IContentProvider provider;
9619        synchronized (this) {
9620            provider = conn.provider.provider;
9621        }
9622
9623        if (provider == null) {
9624            // Um, yeah, we're way ahead of you.
9625            return;
9626        }
9627
9628        // Make sure the caller is being honest with us.
9629        if (provider.asBinder().pingBinder()) {
9630            // Er, no, still looks good to us.
9631            synchronized (this) {
9632                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9633                        + " says " + conn + " died, but we don't agree");
9634                return;
9635            }
9636        }
9637
9638        // Well look at that!  It's dead!
9639        synchronized (this) {
9640            if (conn.provider.provider != provider) {
9641                // But something changed...  good enough.
9642                return;
9643            }
9644
9645            ProcessRecord proc = conn.provider.proc;
9646            if (proc == null || proc.thread == null) {
9647                // Seems like the process is already cleaned up.
9648                return;
9649            }
9650
9651            // As far as we're concerned, this is just like receiving a
9652            // death notification...  just a bit prematurely.
9653            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9654                    + ") early provider death");
9655            final long ident = Binder.clearCallingIdentity();
9656            try {
9657                appDiedLocked(proc);
9658            } finally {
9659                Binder.restoreCallingIdentity(ident);
9660            }
9661        }
9662    }
9663
9664    @Override
9665    public void appNotRespondingViaProvider(IBinder connection) {
9666        enforceCallingPermission(
9667                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9668
9669        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9670        if (conn == null) {
9671            Slog.w(TAG, "ContentProviderConnection is null");
9672            return;
9673        }
9674
9675        final ProcessRecord host = conn.provider.proc;
9676        if (host == null) {
9677            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9678            return;
9679        }
9680
9681        final long token = Binder.clearCallingIdentity();
9682        try {
9683            appNotResponding(host, null, null, false, "ContentProvider not responding");
9684        } finally {
9685            Binder.restoreCallingIdentity(token);
9686        }
9687    }
9688
9689    public final void installSystemProviders() {
9690        List<ProviderInfo> providers;
9691        synchronized (this) {
9692            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9693            providers = generateApplicationProvidersLocked(app);
9694            if (providers != null) {
9695                for (int i=providers.size()-1; i>=0; i--) {
9696                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9697                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9698                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9699                                + ": not system .apk");
9700                        providers.remove(i);
9701                    }
9702                }
9703            }
9704        }
9705        if (providers != null) {
9706            mSystemThread.installSystemProviders(providers);
9707        }
9708
9709        mCoreSettingsObserver = new CoreSettingsObserver(this);
9710
9711        //mUsageStatsService.monitorPackages();
9712    }
9713
9714    /**
9715     * Allows apps to retrieve the MIME type of a URI.
9716     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9717     * users, then it does not need permission to access the ContentProvider.
9718     * Either, it needs cross-user uri grants.
9719     *
9720     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9721     *
9722     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9723     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9724     */
9725    public String getProviderMimeType(Uri uri, int userId) {
9726        enforceNotIsolatedCaller("getProviderMimeType");
9727        final String name = uri.getAuthority();
9728        int callingUid = Binder.getCallingUid();
9729        int callingPid = Binder.getCallingPid();
9730        long ident = 0;
9731        boolean clearedIdentity = false;
9732        userId = unsafeConvertIncomingUser(userId);
9733        if (canClearIdentity(callingPid, callingUid, userId)) {
9734            clearedIdentity = true;
9735            ident = Binder.clearCallingIdentity();
9736        }
9737        ContentProviderHolder holder = null;
9738        try {
9739            holder = getContentProviderExternalUnchecked(name, null, userId);
9740            if (holder != null) {
9741                return holder.provider.getType(uri);
9742            }
9743        } catch (RemoteException e) {
9744            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9745            return null;
9746        } finally {
9747            // We need to clear the identity to call removeContentProviderExternalUnchecked
9748            if (!clearedIdentity) {
9749                ident = Binder.clearCallingIdentity();
9750            }
9751            try {
9752                if (holder != null) {
9753                    removeContentProviderExternalUnchecked(name, null, userId);
9754                }
9755            } finally {
9756                Binder.restoreCallingIdentity(ident);
9757            }
9758        }
9759
9760        return null;
9761    }
9762
9763    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9764        if (UserHandle.getUserId(callingUid) == userId) {
9765            return true;
9766        }
9767        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9768                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9769                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9770                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9771                return true;
9772        }
9773        return false;
9774    }
9775
9776    // =========================================================
9777    // GLOBAL MANAGEMENT
9778    // =========================================================
9779
9780    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9781            boolean isolated, int isolatedUid) {
9782        String proc = customProcess != null ? customProcess : info.processName;
9783        BatteryStatsImpl.Uid.Proc ps = null;
9784        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9785        int uid = info.uid;
9786        if (isolated) {
9787            if (isolatedUid == 0) {
9788                int userId = UserHandle.getUserId(uid);
9789                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9790                while (true) {
9791                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9792                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9793                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9794                    }
9795                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9796                    mNextIsolatedProcessUid++;
9797                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9798                        // No process for this uid, use it.
9799                        break;
9800                    }
9801                    stepsLeft--;
9802                    if (stepsLeft <= 0) {
9803                        return null;
9804                    }
9805                }
9806            } else {
9807                // Special case for startIsolatedProcess (internal only), where
9808                // the uid of the isolated process is specified by the caller.
9809                uid = isolatedUid;
9810            }
9811        }
9812        return new ProcessRecord(stats, info, proc, uid);
9813    }
9814
9815    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9816            String abiOverride) {
9817        ProcessRecord app;
9818        if (!isolated) {
9819            app = getProcessRecordLocked(info.processName, info.uid, true);
9820        } else {
9821            app = null;
9822        }
9823
9824        if (app == null) {
9825            app = newProcessRecordLocked(info, null, isolated, 0);
9826            mProcessNames.put(info.processName, app.uid, app);
9827            if (isolated) {
9828                mIsolatedProcesses.put(app.uid, app);
9829            }
9830            updateLruProcessLocked(app, false, null);
9831            updateOomAdjLocked();
9832        }
9833
9834        // This package really, really can not be stopped.
9835        try {
9836            AppGlobals.getPackageManager().setPackageStoppedState(
9837                    info.packageName, false, UserHandle.getUserId(app.uid));
9838        } catch (RemoteException e) {
9839        } catch (IllegalArgumentException e) {
9840            Slog.w(TAG, "Failed trying to unstop package "
9841                    + info.packageName + ": " + e);
9842        }
9843
9844        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9845                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9846            app.persistent = true;
9847            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9848        }
9849        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9850            mPersistentStartingProcesses.add(app);
9851            startProcessLocked(app, "added application", app.processName, abiOverride,
9852                    null /* entryPoint */, null /* entryPointArgs */);
9853        }
9854
9855        return app;
9856    }
9857
9858    public void unhandledBack() {
9859        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9860                "unhandledBack()");
9861
9862        synchronized(this) {
9863            final long origId = Binder.clearCallingIdentity();
9864            try {
9865                getFocusedStack().unhandledBackLocked();
9866            } finally {
9867                Binder.restoreCallingIdentity(origId);
9868            }
9869        }
9870    }
9871
9872    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9873        enforceNotIsolatedCaller("openContentUri");
9874        final int userId = UserHandle.getCallingUserId();
9875        String name = uri.getAuthority();
9876        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9877        ParcelFileDescriptor pfd = null;
9878        if (cph != null) {
9879            // We record the binder invoker's uid in thread-local storage before
9880            // going to the content provider to open the file.  Later, in the code
9881            // that handles all permissions checks, we look for this uid and use
9882            // that rather than the Activity Manager's own uid.  The effect is that
9883            // we do the check against the caller's permissions even though it looks
9884            // to the content provider like the Activity Manager itself is making
9885            // the request.
9886            sCallerIdentity.set(new Identity(
9887                    Binder.getCallingPid(), Binder.getCallingUid()));
9888            try {
9889                pfd = cph.provider.openFile(null, uri, "r", null);
9890            } catch (FileNotFoundException e) {
9891                // do nothing; pfd will be returned null
9892            } finally {
9893                // Ensure that whatever happens, we clean up the identity state
9894                sCallerIdentity.remove();
9895            }
9896
9897            // We've got the fd now, so we're done with the provider.
9898            removeContentProviderExternalUnchecked(name, null, userId);
9899        } else {
9900            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9901        }
9902        return pfd;
9903    }
9904
9905    // Actually is sleeping or shutting down or whatever else in the future
9906    // is an inactive state.
9907    public boolean isSleepingOrShuttingDown() {
9908        return isSleeping() || mShuttingDown;
9909    }
9910
9911    public boolean isSleeping() {
9912        return mSleeping && !mKeyguardWaitingForDraw;
9913    }
9914
9915    void goingToSleep() {
9916        synchronized(this) {
9917            mWentToSleep = true;
9918            updateEventDispatchingLocked();
9919            goToSleepIfNeededLocked();
9920        }
9921    }
9922
9923    void finishRunningVoiceLocked() {
9924        if (mRunningVoice) {
9925            mRunningVoice = false;
9926            goToSleepIfNeededLocked();
9927        }
9928    }
9929
9930    void goToSleepIfNeededLocked() {
9931        if (mWentToSleep && !mRunningVoice) {
9932            if (!mSleeping) {
9933                mSleeping = true;
9934                mKeyguardWaitingForDraw = false;
9935                mStackSupervisor.goingToSleepLocked();
9936
9937                // Initialize the wake times of all processes.
9938                checkExcessivePowerUsageLocked(false);
9939                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9940                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9941                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9942            }
9943        }
9944    }
9945
9946    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9947        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9948            // Never persist the home stack.
9949            return;
9950        }
9951        mTaskPersister.wakeup(task, flush);
9952    }
9953
9954    @Override
9955    public boolean shutdown(int timeout) {
9956        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9957                != PackageManager.PERMISSION_GRANTED) {
9958            throw new SecurityException("Requires permission "
9959                    + android.Manifest.permission.SHUTDOWN);
9960        }
9961
9962        boolean timedout = false;
9963
9964        synchronized(this) {
9965            mShuttingDown = true;
9966            updateEventDispatchingLocked();
9967            timedout = mStackSupervisor.shutdownLocked(timeout);
9968        }
9969
9970        mAppOpsService.shutdown();
9971        if (mUsageStatsService != null) {
9972            mUsageStatsService.prepareShutdown();
9973        }
9974        mBatteryStatsService.shutdown();
9975        synchronized (this) {
9976            mProcessStats.shutdownLocked();
9977        }
9978        notifyTaskPersisterLocked(null, true);
9979
9980        return timedout;
9981    }
9982
9983    public final void activitySlept(IBinder token) {
9984        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9985
9986        final long origId = Binder.clearCallingIdentity();
9987
9988        synchronized (this) {
9989            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9990            if (r != null) {
9991                mStackSupervisor.activitySleptLocked(r);
9992            }
9993        }
9994
9995        Binder.restoreCallingIdentity(origId);
9996    }
9997
9998    void logLockScreen(String msg) {
9999        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10000                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10001                mWentToSleep + " mSleeping=" + mSleeping);
10002    }
10003
10004    private void comeOutOfSleepIfNeededLocked() {
10005        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10006            if (mSleeping) {
10007                mSleeping = false;
10008                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10009            }
10010        }
10011    }
10012
10013    void wakingUp() {
10014        synchronized(this) {
10015            mWentToSleep = false;
10016            updateEventDispatchingLocked();
10017            comeOutOfSleepIfNeededLocked();
10018        }
10019    }
10020
10021    void startRunningVoiceLocked() {
10022        if (!mRunningVoice) {
10023            mRunningVoice = true;
10024            comeOutOfSleepIfNeededLocked();
10025        }
10026    }
10027
10028    private void updateEventDispatchingLocked() {
10029        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10030    }
10031
10032    public void setLockScreenShown(boolean shown) {
10033        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10034                != PackageManager.PERMISSION_GRANTED) {
10035            throw new SecurityException("Requires permission "
10036                    + android.Manifest.permission.DEVICE_POWER);
10037        }
10038
10039        synchronized(this) {
10040            long ident = Binder.clearCallingIdentity();
10041            try {
10042                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10043                mLockScreenShown = shown;
10044                mKeyguardWaitingForDraw = false;
10045                comeOutOfSleepIfNeededLocked();
10046            } finally {
10047                Binder.restoreCallingIdentity(ident);
10048            }
10049        }
10050    }
10051
10052    @Override
10053    public void stopAppSwitches() {
10054        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10055                != PackageManager.PERMISSION_GRANTED) {
10056            throw new SecurityException("Requires permission "
10057                    + android.Manifest.permission.STOP_APP_SWITCHES);
10058        }
10059
10060        synchronized(this) {
10061            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10062                    + APP_SWITCH_DELAY_TIME;
10063            mDidAppSwitch = false;
10064            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10065            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10066            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10067        }
10068    }
10069
10070    public void resumeAppSwitches() {
10071        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10072                != PackageManager.PERMISSION_GRANTED) {
10073            throw new SecurityException("Requires permission "
10074                    + android.Manifest.permission.STOP_APP_SWITCHES);
10075        }
10076
10077        synchronized(this) {
10078            // Note that we don't execute any pending app switches... we will
10079            // let those wait until either the timeout, or the next start
10080            // activity request.
10081            mAppSwitchesAllowedTime = 0;
10082        }
10083    }
10084
10085    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10086            String name) {
10087        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10088            return true;
10089        }
10090
10091        final int perm = checkComponentPermission(
10092                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10093                callingUid, -1, true);
10094        if (perm == PackageManager.PERMISSION_GRANTED) {
10095            return true;
10096        }
10097
10098        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10099        return false;
10100    }
10101
10102    public void setDebugApp(String packageName, boolean waitForDebugger,
10103            boolean persistent) {
10104        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10105                "setDebugApp()");
10106
10107        long ident = Binder.clearCallingIdentity();
10108        try {
10109            // Note that this is not really thread safe if there are multiple
10110            // callers into it at the same time, but that's not a situation we
10111            // care about.
10112            if (persistent) {
10113                final ContentResolver resolver = mContext.getContentResolver();
10114                Settings.Global.putString(
10115                    resolver, Settings.Global.DEBUG_APP,
10116                    packageName);
10117                Settings.Global.putInt(
10118                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10119                    waitForDebugger ? 1 : 0);
10120            }
10121
10122            synchronized (this) {
10123                if (!persistent) {
10124                    mOrigDebugApp = mDebugApp;
10125                    mOrigWaitForDebugger = mWaitForDebugger;
10126                }
10127                mDebugApp = packageName;
10128                mWaitForDebugger = waitForDebugger;
10129                mDebugTransient = !persistent;
10130                if (packageName != null) {
10131                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10132                            false, UserHandle.USER_ALL, "set debug app");
10133                }
10134            }
10135        } finally {
10136            Binder.restoreCallingIdentity(ident);
10137        }
10138    }
10139
10140    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10141        synchronized (this) {
10142            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10143            if (!isDebuggable) {
10144                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10145                    throw new SecurityException("Process not debuggable: " + app.packageName);
10146                }
10147            }
10148
10149            mOpenGlTraceApp = processName;
10150        }
10151    }
10152
10153    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10154        synchronized (this) {
10155            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10156            if (!isDebuggable) {
10157                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10158                    throw new SecurityException("Process not debuggable: " + app.packageName);
10159                }
10160            }
10161            mProfileApp = processName;
10162            mProfileFile = profilerInfo.profileFile;
10163            if (mProfileFd != null) {
10164                try {
10165                    mProfileFd.close();
10166                } catch (IOException e) {
10167                }
10168                mProfileFd = null;
10169            }
10170            mProfileFd = profilerInfo.profileFd;
10171            mSamplingInterval = profilerInfo.samplingInterval;
10172            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10173            mProfileType = 0;
10174        }
10175    }
10176
10177    @Override
10178    public void setAlwaysFinish(boolean enabled) {
10179        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10180                "setAlwaysFinish()");
10181
10182        Settings.Global.putInt(
10183                mContext.getContentResolver(),
10184                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10185
10186        synchronized (this) {
10187            mAlwaysFinishActivities = enabled;
10188        }
10189    }
10190
10191    @Override
10192    public void setActivityController(IActivityController controller) {
10193        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10194                "setActivityController()");
10195        synchronized (this) {
10196            mController = controller;
10197            Watchdog.getInstance().setActivityController(controller);
10198        }
10199    }
10200
10201    @Override
10202    public void setUserIsMonkey(boolean userIsMonkey) {
10203        synchronized (this) {
10204            synchronized (mPidsSelfLocked) {
10205                final int callingPid = Binder.getCallingPid();
10206                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10207                if (precessRecord == null) {
10208                    throw new SecurityException("Unknown process: " + callingPid);
10209                }
10210                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10211                    throw new SecurityException("Only an instrumentation process "
10212                            + "with a UiAutomation can call setUserIsMonkey");
10213                }
10214            }
10215            mUserIsMonkey = userIsMonkey;
10216        }
10217    }
10218
10219    @Override
10220    public boolean isUserAMonkey() {
10221        synchronized (this) {
10222            // If there is a controller also implies the user is a monkey.
10223            return (mUserIsMonkey || mController != null);
10224        }
10225    }
10226
10227    public void requestBugReport() {
10228        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10229        SystemProperties.set("ctl.start", "bugreport");
10230    }
10231
10232    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10233        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10234    }
10235
10236    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10237        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10238            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10239        }
10240        return KEY_DISPATCHING_TIMEOUT;
10241    }
10242
10243    @Override
10244    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10245        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10246                != PackageManager.PERMISSION_GRANTED) {
10247            throw new SecurityException("Requires permission "
10248                    + android.Manifest.permission.FILTER_EVENTS);
10249        }
10250        ProcessRecord proc;
10251        long timeout;
10252        synchronized (this) {
10253            synchronized (mPidsSelfLocked) {
10254                proc = mPidsSelfLocked.get(pid);
10255            }
10256            timeout = getInputDispatchingTimeoutLocked(proc);
10257        }
10258
10259        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10260            return -1;
10261        }
10262
10263        return timeout;
10264    }
10265
10266    /**
10267     * Handle input dispatching timeouts.
10268     * Returns whether input dispatching should be aborted or not.
10269     */
10270    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10271            final ActivityRecord activity, final ActivityRecord parent,
10272            final boolean aboveSystem, String reason) {
10273        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10274                != PackageManager.PERMISSION_GRANTED) {
10275            throw new SecurityException("Requires permission "
10276                    + android.Manifest.permission.FILTER_EVENTS);
10277        }
10278
10279        final String annotation;
10280        if (reason == null) {
10281            annotation = "Input dispatching timed out";
10282        } else {
10283            annotation = "Input dispatching timed out (" + reason + ")";
10284        }
10285
10286        if (proc != null) {
10287            synchronized (this) {
10288                if (proc.debugging) {
10289                    return false;
10290                }
10291
10292                if (mDidDexOpt) {
10293                    // Give more time since we were dexopting.
10294                    mDidDexOpt = false;
10295                    return false;
10296                }
10297
10298                if (proc.instrumentationClass != null) {
10299                    Bundle info = new Bundle();
10300                    info.putString("shortMsg", "keyDispatchingTimedOut");
10301                    info.putString("longMsg", annotation);
10302                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10303                    return true;
10304                }
10305            }
10306            mHandler.post(new Runnable() {
10307                @Override
10308                public void run() {
10309                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10310                }
10311            });
10312        }
10313
10314        return true;
10315    }
10316
10317    public Bundle getAssistContextExtras(int requestType) {
10318        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10319                "getAssistContextExtras()");
10320        PendingAssistExtras pae;
10321        Bundle extras = new Bundle();
10322        synchronized (this) {
10323            ActivityRecord activity = getFocusedStack().mResumedActivity;
10324            if (activity == null) {
10325                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10326                return null;
10327            }
10328            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10329            if (activity.app == null || activity.app.thread == null) {
10330                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10331                return extras;
10332            }
10333            if (activity.app.pid == Binder.getCallingPid()) {
10334                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10335                return extras;
10336            }
10337            pae = new PendingAssistExtras(activity);
10338            try {
10339                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10340                        requestType);
10341                mPendingAssistExtras.add(pae);
10342                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10343            } catch (RemoteException e) {
10344                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10345                return extras;
10346            }
10347        }
10348        synchronized (pae) {
10349            while (!pae.haveResult) {
10350                try {
10351                    pae.wait();
10352                } catch (InterruptedException e) {
10353                }
10354            }
10355            if (pae.result != null) {
10356                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10357            }
10358        }
10359        synchronized (this) {
10360            mPendingAssistExtras.remove(pae);
10361            mHandler.removeCallbacks(pae);
10362        }
10363        return extras;
10364    }
10365
10366    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10367        PendingAssistExtras pae = (PendingAssistExtras)token;
10368        synchronized (pae) {
10369            pae.result = extras;
10370            pae.haveResult = true;
10371            pae.notifyAll();
10372        }
10373    }
10374
10375    public void registerProcessObserver(IProcessObserver observer) {
10376        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10377                "registerProcessObserver()");
10378        synchronized (this) {
10379            mProcessObservers.register(observer);
10380        }
10381    }
10382
10383    @Override
10384    public void unregisterProcessObserver(IProcessObserver observer) {
10385        synchronized (this) {
10386            mProcessObservers.unregister(observer);
10387        }
10388    }
10389
10390    @Override
10391    public boolean convertFromTranslucent(IBinder token) {
10392        final long origId = Binder.clearCallingIdentity();
10393        try {
10394            synchronized (this) {
10395                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10396                if (r == null) {
10397                    return false;
10398                }
10399                final boolean translucentChanged = r.changeWindowTranslucency(true);
10400                if (translucentChanged) {
10401                    r.task.stack.releaseBackgroundResources();
10402                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10403                }
10404                mWindowManager.setAppFullscreen(token, true);
10405                return translucentChanged;
10406            }
10407        } finally {
10408            Binder.restoreCallingIdentity(origId);
10409        }
10410    }
10411
10412    @Override
10413    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10414        final long origId = Binder.clearCallingIdentity();
10415        try {
10416            synchronized (this) {
10417                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10418                if (r == null) {
10419                    return false;
10420                }
10421                int index = r.task.mActivities.lastIndexOf(r);
10422                if (index > 0) {
10423                    ActivityRecord under = r.task.mActivities.get(index - 1);
10424                    under.returningOptions = options;
10425                }
10426                final boolean translucentChanged = r.changeWindowTranslucency(false);
10427                if (translucentChanged) {
10428                    r.task.stack.convertToTranslucent(r);
10429                }
10430                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10431                mWindowManager.setAppFullscreen(token, false);
10432                return translucentChanged;
10433            }
10434        } finally {
10435            Binder.restoreCallingIdentity(origId);
10436        }
10437    }
10438
10439    @Override
10440    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10441        final long origId = Binder.clearCallingIdentity();
10442        try {
10443            synchronized (this) {
10444                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10445                if (r != null) {
10446                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10447                }
10448            }
10449            return false;
10450        } finally {
10451            Binder.restoreCallingIdentity(origId);
10452        }
10453    }
10454
10455    @Override
10456    public boolean isBackgroundVisibleBehind(IBinder token) {
10457        final long origId = Binder.clearCallingIdentity();
10458        try {
10459            synchronized (this) {
10460                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10461                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10462                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10463                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10464                return visible;
10465            }
10466        } finally {
10467            Binder.restoreCallingIdentity(origId);
10468        }
10469    }
10470
10471    @Override
10472    public ActivityOptions getActivityOptions(IBinder token) {
10473        final long origId = Binder.clearCallingIdentity();
10474        try {
10475            synchronized (this) {
10476                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10477                if (r != null) {
10478                    final ActivityOptions activityOptions = r.pendingOptions;
10479                    r.pendingOptions = null;
10480                    return activityOptions;
10481                }
10482                return null;
10483            }
10484        } finally {
10485            Binder.restoreCallingIdentity(origId);
10486        }
10487    }
10488
10489    @Override
10490    public void setImmersive(IBinder token, boolean immersive) {
10491        synchronized(this) {
10492            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10493            if (r == null) {
10494                throw new IllegalArgumentException();
10495            }
10496            r.immersive = immersive;
10497
10498            // update associated state if we're frontmost
10499            if (r == mFocusedActivity) {
10500                if (DEBUG_IMMERSIVE) {
10501                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10502                }
10503                applyUpdateLockStateLocked(r);
10504            }
10505        }
10506    }
10507
10508    @Override
10509    public boolean isImmersive(IBinder token) {
10510        synchronized (this) {
10511            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10512            if (r == null) {
10513                throw new IllegalArgumentException();
10514            }
10515            return r.immersive;
10516        }
10517    }
10518
10519    public boolean isTopActivityImmersive() {
10520        enforceNotIsolatedCaller("startActivity");
10521        synchronized (this) {
10522            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10523            return (r != null) ? r.immersive : false;
10524        }
10525    }
10526
10527    @Override
10528    public boolean isTopOfTask(IBinder token) {
10529        synchronized (this) {
10530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10531            if (r == null) {
10532                throw new IllegalArgumentException();
10533            }
10534            return r.task.getTopActivity() == r;
10535        }
10536    }
10537
10538    public final void enterSafeMode() {
10539        synchronized(this) {
10540            // It only makes sense to do this before the system is ready
10541            // and started launching other packages.
10542            if (!mSystemReady) {
10543                try {
10544                    AppGlobals.getPackageManager().enterSafeMode();
10545                } catch (RemoteException e) {
10546                }
10547            }
10548
10549            mSafeMode = true;
10550        }
10551    }
10552
10553    public final void showSafeModeOverlay() {
10554        View v = LayoutInflater.from(mContext).inflate(
10555                com.android.internal.R.layout.safe_mode, null);
10556        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10557        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10558        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10559        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10560        lp.gravity = Gravity.BOTTOM | Gravity.START;
10561        lp.format = v.getBackground().getOpacity();
10562        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10563                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10564        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10565        ((WindowManager)mContext.getSystemService(
10566                Context.WINDOW_SERVICE)).addView(v, lp);
10567    }
10568
10569    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10570        if (!(sender instanceof PendingIntentRecord)) {
10571            return;
10572        }
10573        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10574        synchronized (stats) {
10575            if (mBatteryStatsService.isOnBattery()) {
10576                mBatteryStatsService.enforceCallingPermission();
10577                PendingIntentRecord rec = (PendingIntentRecord)sender;
10578                int MY_UID = Binder.getCallingUid();
10579                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10580                BatteryStatsImpl.Uid.Pkg pkg =
10581                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10582                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10583                pkg.incWakeupsLocked();
10584            }
10585        }
10586    }
10587
10588    public boolean killPids(int[] pids, String pReason, boolean secure) {
10589        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10590            throw new SecurityException("killPids only available to the system");
10591        }
10592        String reason = (pReason == null) ? "Unknown" : pReason;
10593        // XXX Note: don't acquire main activity lock here, because the window
10594        // manager calls in with its locks held.
10595
10596        boolean killed = false;
10597        synchronized (mPidsSelfLocked) {
10598            int[] types = new int[pids.length];
10599            int worstType = 0;
10600            for (int i=0; i<pids.length; i++) {
10601                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10602                if (proc != null) {
10603                    int type = proc.setAdj;
10604                    types[i] = type;
10605                    if (type > worstType) {
10606                        worstType = type;
10607                    }
10608                }
10609            }
10610
10611            // If the worst oom_adj is somewhere in the cached proc LRU range,
10612            // then constrain it so we will kill all cached procs.
10613            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10614                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10615                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10616            }
10617
10618            // If this is not a secure call, don't let it kill processes that
10619            // are important.
10620            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10621                worstType = ProcessList.SERVICE_ADJ;
10622            }
10623
10624            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10625            for (int i=0; i<pids.length; i++) {
10626                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10627                if (proc == null) {
10628                    continue;
10629                }
10630                int adj = proc.setAdj;
10631                if (adj >= worstType && !proc.killedByAm) {
10632                    proc.kill(reason, true);
10633                    killed = true;
10634                }
10635            }
10636        }
10637        return killed;
10638    }
10639
10640    @Override
10641    public void killUid(int uid, String reason) {
10642        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10643            throw new SecurityException("killUid only available to the system");
10644        }
10645        synchronized (this) {
10646            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10647                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10648                    reason != null ? reason : "kill uid");
10649        }
10650    }
10651
10652    @Override
10653    public boolean killProcessesBelowForeground(String reason) {
10654        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10655            throw new SecurityException("killProcessesBelowForeground() only available to system");
10656        }
10657
10658        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10659    }
10660
10661    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10662        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10663            throw new SecurityException("killProcessesBelowAdj() only available to system");
10664        }
10665
10666        boolean killed = false;
10667        synchronized (mPidsSelfLocked) {
10668            final int size = mPidsSelfLocked.size();
10669            for (int i = 0; i < size; i++) {
10670                final int pid = mPidsSelfLocked.keyAt(i);
10671                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10672                if (proc == null) continue;
10673
10674                final int adj = proc.setAdj;
10675                if (adj > belowAdj && !proc.killedByAm) {
10676                    proc.kill(reason, true);
10677                    killed = true;
10678                }
10679            }
10680        }
10681        return killed;
10682    }
10683
10684    @Override
10685    public void hang(final IBinder who, boolean allowRestart) {
10686        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10687                != PackageManager.PERMISSION_GRANTED) {
10688            throw new SecurityException("Requires permission "
10689                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10690        }
10691
10692        final IBinder.DeathRecipient death = new DeathRecipient() {
10693            @Override
10694            public void binderDied() {
10695                synchronized (this) {
10696                    notifyAll();
10697                }
10698            }
10699        };
10700
10701        try {
10702            who.linkToDeath(death, 0);
10703        } catch (RemoteException e) {
10704            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10705            return;
10706        }
10707
10708        synchronized (this) {
10709            Watchdog.getInstance().setAllowRestart(allowRestart);
10710            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10711            synchronized (death) {
10712                while (who.isBinderAlive()) {
10713                    try {
10714                        death.wait();
10715                    } catch (InterruptedException e) {
10716                    }
10717                }
10718            }
10719            Watchdog.getInstance().setAllowRestart(true);
10720        }
10721    }
10722
10723    @Override
10724    public void restart() {
10725        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10726                != PackageManager.PERMISSION_GRANTED) {
10727            throw new SecurityException("Requires permission "
10728                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10729        }
10730
10731        Log.i(TAG, "Sending shutdown broadcast...");
10732
10733        BroadcastReceiver br = new BroadcastReceiver() {
10734            @Override public void onReceive(Context context, Intent intent) {
10735                // Now the broadcast is done, finish up the low-level shutdown.
10736                Log.i(TAG, "Shutting down activity manager...");
10737                shutdown(10000);
10738                Log.i(TAG, "Shutdown complete, restarting!");
10739                Process.killProcess(Process.myPid());
10740                System.exit(10);
10741            }
10742        };
10743
10744        // First send the high-level shut down broadcast.
10745        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10746        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10747        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10748        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10749        mContext.sendOrderedBroadcastAsUser(intent,
10750                UserHandle.ALL, null, br, mHandler, 0, null, null);
10751        */
10752        br.onReceive(mContext, intent);
10753    }
10754
10755    private long getLowRamTimeSinceIdle(long now) {
10756        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10757    }
10758
10759    @Override
10760    public void performIdleMaintenance() {
10761        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10762                != PackageManager.PERMISSION_GRANTED) {
10763            throw new SecurityException("Requires permission "
10764                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10765        }
10766
10767        synchronized (this) {
10768            final long now = SystemClock.uptimeMillis();
10769            final long timeSinceLastIdle = now - mLastIdleTime;
10770            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10771            mLastIdleTime = now;
10772            mLowRamTimeSinceLastIdle = 0;
10773            if (mLowRamStartTime != 0) {
10774                mLowRamStartTime = now;
10775            }
10776
10777            StringBuilder sb = new StringBuilder(128);
10778            sb.append("Idle maintenance over ");
10779            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10780            sb.append(" low RAM for ");
10781            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10782            Slog.i(TAG, sb.toString());
10783
10784            // If at least 1/3 of our time since the last idle period has been spent
10785            // with RAM low, then we want to kill processes.
10786            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10787
10788            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10789                ProcessRecord proc = mLruProcesses.get(i);
10790                if (proc.notCachedSinceIdle) {
10791                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10792                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10793                        if (doKilling && proc.initialIdlePss != 0
10794                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10795                            proc.kill("idle maint (pss " + proc.lastPss
10796                                    + " from " + proc.initialIdlePss + ")", true);
10797                        }
10798                    }
10799                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10800                    proc.notCachedSinceIdle = true;
10801                    proc.initialIdlePss = 0;
10802                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10803                            isSleeping(), now);
10804                }
10805            }
10806
10807            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10808            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10809        }
10810    }
10811
10812    private void retrieveSettings() {
10813        final ContentResolver resolver = mContext.getContentResolver();
10814        String debugApp = Settings.Global.getString(
10815            resolver, Settings.Global.DEBUG_APP);
10816        boolean waitForDebugger = Settings.Global.getInt(
10817            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10818        boolean alwaysFinishActivities = Settings.Global.getInt(
10819            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10820        boolean forceRtl = Settings.Global.getInt(
10821                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10822        // Transfer any global setting for forcing RTL layout, into a System Property
10823        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10824
10825        Configuration configuration = new Configuration();
10826        Settings.System.getConfiguration(resolver, configuration);
10827        if (forceRtl) {
10828            // This will take care of setting the correct layout direction flags
10829            configuration.setLayoutDirection(configuration.locale);
10830        }
10831
10832        synchronized (this) {
10833            mDebugApp = mOrigDebugApp = debugApp;
10834            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10835            mAlwaysFinishActivities = alwaysFinishActivities;
10836            // This happens before any activities are started, so we can
10837            // change mConfiguration in-place.
10838            updateConfigurationLocked(configuration, null, false, true);
10839            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10840        }
10841    }
10842
10843    /** Loads resources after the current configuration has been set. */
10844    private void loadResourcesOnSystemReady() {
10845        final Resources res = mContext.getResources();
10846        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10847        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10848        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10849    }
10850
10851    public boolean testIsSystemReady() {
10852        // no need to synchronize(this) just to read & return the value
10853        return mSystemReady;
10854    }
10855
10856    private static File getCalledPreBootReceiversFile() {
10857        File dataDir = Environment.getDataDirectory();
10858        File systemDir = new File(dataDir, "system");
10859        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10860        return fname;
10861    }
10862
10863    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10864        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10865        File file = getCalledPreBootReceiversFile();
10866        FileInputStream fis = null;
10867        try {
10868            fis = new FileInputStream(file);
10869            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10870            int fvers = dis.readInt();
10871            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10872                String vers = dis.readUTF();
10873                String codename = dis.readUTF();
10874                String build = dis.readUTF();
10875                if (android.os.Build.VERSION.RELEASE.equals(vers)
10876                        && android.os.Build.VERSION.CODENAME.equals(codename)
10877                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10878                    int num = dis.readInt();
10879                    while (num > 0) {
10880                        num--;
10881                        String pkg = dis.readUTF();
10882                        String cls = dis.readUTF();
10883                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10884                    }
10885                }
10886            }
10887        } catch (FileNotFoundException e) {
10888        } catch (IOException e) {
10889            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10890        } finally {
10891            if (fis != null) {
10892                try {
10893                    fis.close();
10894                } catch (IOException e) {
10895                }
10896            }
10897        }
10898        return lastDoneReceivers;
10899    }
10900
10901    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10902        File file = getCalledPreBootReceiversFile();
10903        FileOutputStream fos = null;
10904        DataOutputStream dos = null;
10905        try {
10906            fos = new FileOutputStream(file);
10907            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10908            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10909            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10910            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10911            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10912            dos.writeInt(list.size());
10913            for (int i=0; i<list.size(); i++) {
10914                dos.writeUTF(list.get(i).getPackageName());
10915                dos.writeUTF(list.get(i).getClassName());
10916            }
10917        } catch (IOException e) {
10918            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10919            file.delete();
10920        } finally {
10921            FileUtils.sync(fos);
10922            if (dos != null) {
10923                try {
10924                    dos.close();
10925                } catch (IOException e) {
10926                    // TODO Auto-generated catch block
10927                    e.printStackTrace();
10928                }
10929            }
10930        }
10931    }
10932
10933    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10934            ArrayList<ComponentName> doneReceivers, int userId) {
10935        boolean waitingUpdate = false;
10936        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10937        List<ResolveInfo> ris = null;
10938        try {
10939            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10940                    intent, null, 0, userId);
10941        } catch (RemoteException e) {
10942        }
10943        if (ris != null) {
10944            for (int i=ris.size()-1; i>=0; i--) {
10945                if ((ris.get(i).activityInfo.applicationInfo.flags
10946                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10947                    ris.remove(i);
10948                }
10949            }
10950            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10951
10952            // For User 0, load the version number. When delivering to a new user, deliver
10953            // to all receivers.
10954            if (userId == UserHandle.USER_OWNER) {
10955                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10956                for (int i=0; i<ris.size(); i++) {
10957                    ActivityInfo ai = ris.get(i).activityInfo;
10958                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10959                    if (lastDoneReceivers.contains(comp)) {
10960                        // We already did the pre boot receiver for this app with the current
10961                        // platform version, so don't do it again...
10962                        ris.remove(i);
10963                        i--;
10964                        // ...however, do keep it as one that has been done, so we don't
10965                        // forget about it when rewriting the file of last done receivers.
10966                        doneReceivers.add(comp);
10967                    }
10968                }
10969            }
10970
10971            // If primary user, send broadcast to all available users, else just to userId
10972            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10973                    : new int[] { userId };
10974            for (int i = 0; i < ris.size(); i++) {
10975                ActivityInfo ai = ris.get(i).activityInfo;
10976                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10977                doneReceivers.add(comp);
10978                intent.setComponent(comp);
10979                for (int j=0; j<users.length; j++) {
10980                    IIntentReceiver finisher = null;
10981                    // On last receiver and user, set up a completion callback
10982                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10983                        finisher = new IIntentReceiver.Stub() {
10984                            public void performReceive(Intent intent, int resultCode,
10985                                    String data, Bundle extras, boolean ordered,
10986                                    boolean sticky, int sendingUser) {
10987                                // The raw IIntentReceiver interface is called
10988                                // with the AM lock held, so redispatch to
10989                                // execute our code without the lock.
10990                                mHandler.post(onFinishCallback);
10991                            }
10992                        };
10993                    }
10994                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10995                            + " for user " + users[j]);
10996                    broadcastIntentLocked(null, null, intent, null, finisher,
10997                            0, null, null, null, AppOpsManager.OP_NONE,
10998                            true, false, MY_PID, Process.SYSTEM_UID,
10999                            users[j]);
11000                    if (finisher != null) {
11001                        waitingUpdate = true;
11002                    }
11003                }
11004            }
11005        }
11006
11007        return waitingUpdate;
11008    }
11009
11010    public void systemReady(final Runnable goingCallback) {
11011        synchronized(this) {
11012            if (mSystemReady) {
11013                // If we're done calling all the receivers, run the next "boot phase" passed in
11014                // by the SystemServer
11015                if (goingCallback != null) {
11016                    goingCallback.run();
11017                }
11018                return;
11019            }
11020
11021            // Make sure we have the current profile info, since it is needed for
11022            // security checks.
11023            updateCurrentProfileIdsLocked();
11024
11025            if (mRecentTasks == null) {
11026                mRecentTasks = mTaskPersister.restoreTasksLocked();
11027                if (!mRecentTasks.isEmpty()) {
11028                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11029                }
11030                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11031                mTaskPersister.startPersisting();
11032            }
11033
11034            // Check to see if there are any update receivers to run.
11035            if (!mDidUpdate) {
11036                if (mWaitingUpdate) {
11037                    return;
11038                }
11039                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11040                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11041                    public void run() {
11042                        synchronized (ActivityManagerService.this) {
11043                            mDidUpdate = true;
11044                        }
11045                        writeLastDonePreBootReceivers(doneReceivers);
11046                        showBootMessage(mContext.getText(
11047                                R.string.android_upgrading_complete),
11048                                false);
11049                        systemReady(goingCallback);
11050                    }
11051                }, doneReceivers, UserHandle.USER_OWNER);
11052
11053                if (mWaitingUpdate) {
11054                    return;
11055                }
11056                mDidUpdate = true;
11057            }
11058
11059            mAppOpsService.systemReady();
11060            mSystemReady = true;
11061        }
11062
11063        ArrayList<ProcessRecord> procsToKill = null;
11064        synchronized(mPidsSelfLocked) {
11065            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11066                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11067                if (!isAllowedWhileBooting(proc.info)){
11068                    if (procsToKill == null) {
11069                        procsToKill = new ArrayList<ProcessRecord>();
11070                    }
11071                    procsToKill.add(proc);
11072                }
11073            }
11074        }
11075
11076        synchronized(this) {
11077            if (procsToKill != null) {
11078                for (int i=procsToKill.size()-1; i>=0; i--) {
11079                    ProcessRecord proc = procsToKill.get(i);
11080                    Slog.i(TAG, "Removing system update proc: " + proc);
11081                    removeProcessLocked(proc, true, false, "system update done");
11082                }
11083            }
11084
11085            // Now that we have cleaned up any update processes, we
11086            // are ready to start launching real processes and know that
11087            // we won't trample on them any more.
11088            mProcessesReady = true;
11089        }
11090
11091        Slog.i(TAG, "System now ready");
11092        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11093            SystemClock.uptimeMillis());
11094
11095        synchronized(this) {
11096            // Make sure we have no pre-ready processes sitting around.
11097
11098            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11099                ResolveInfo ri = mContext.getPackageManager()
11100                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11101                                STOCK_PM_FLAGS);
11102                CharSequence errorMsg = null;
11103                if (ri != null) {
11104                    ActivityInfo ai = ri.activityInfo;
11105                    ApplicationInfo app = ai.applicationInfo;
11106                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11107                        mTopAction = Intent.ACTION_FACTORY_TEST;
11108                        mTopData = null;
11109                        mTopComponent = new ComponentName(app.packageName,
11110                                ai.name);
11111                    } else {
11112                        errorMsg = mContext.getResources().getText(
11113                                com.android.internal.R.string.factorytest_not_system);
11114                    }
11115                } else {
11116                    errorMsg = mContext.getResources().getText(
11117                            com.android.internal.R.string.factorytest_no_action);
11118                }
11119                if (errorMsg != null) {
11120                    mTopAction = null;
11121                    mTopData = null;
11122                    mTopComponent = null;
11123                    Message msg = Message.obtain();
11124                    msg.what = SHOW_FACTORY_ERROR_MSG;
11125                    msg.getData().putCharSequence("msg", errorMsg);
11126                    mHandler.sendMessage(msg);
11127                }
11128            }
11129        }
11130
11131        retrieveSettings();
11132        loadResourcesOnSystemReady();
11133
11134        synchronized (this) {
11135            readGrantedUriPermissionsLocked();
11136        }
11137
11138        if (goingCallback != null) goingCallback.run();
11139
11140        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11141                Integer.toString(mCurrentUserId), mCurrentUserId);
11142        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11143                Integer.toString(mCurrentUserId), mCurrentUserId);
11144        mSystemServiceManager.startUser(mCurrentUserId);
11145
11146        synchronized (this) {
11147            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11148                try {
11149                    List apps = AppGlobals.getPackageManager().
11150                        getPersistentApplications(STOCK_PM_FLAGS);
11151                    if (apps != null) {
11152                        int N = apps.size();
11153                        int i;
11154                        for (i=0; i<N; i++) {
11155                            ApplicationInfo info
11156                                = (ApplicationInfo)apps.get(i);
11157                            if (info != null &&
11158                                    !info.packageName.equals("android")) {
11159                                addAppLocked(info, false, null /* ABI override */);
11160                            }
11161                        }
11162                    }
11163                } catch (RemoteException ex) {
11164                    // pm is in same process, this will never happen.
11165                }
11166            }
11167
11168            // Start up initial activity.
11169            mBooting = true;
11170
11171            try {
11172                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11173                    Message msg = Message.obtain();
11174                    msg.what = SHOW_UID_ERROR_MSG;
11175                    mHandler.sendMessage(msg);
11176                }
11177            } catch (RemoteException e) {
11178            }
11179
11180            long ident = Binder.clearCallingIdentity();
11181            try {
11182                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11183                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11184                        | Intent.FLAG_RECEIVER_FOREGROUND);
11185                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11186                broadcastIntentLocked(null, null, intent,
11187                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11188                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11189                intent = new Intent(Intent.ACTION_USER_STARTING);
11190                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11191                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11192                broadcastIntentLocked(null, null, intent,
11193                        null, new IIntentReceiver.Stub() {
11194                            @Override
11195                            public void performReceive(Intent intent, int resultCode, String data,
11196                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11197                                    throws RemoteException {
11198                            }
11199                        }, 0, null, null,
11200                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11201                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11202            } catch (Throwable t) {
11203                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11204            } finally {
11205                Binder.restoreCallingIdentity(ident);
11206            }
11207            mStackSupervisor.resumeTopActivitiesLocked();
11208            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11209        }
11210    }
11211
11212    private boolean makeAppCrashingLocked(ProcessRecord app,
11213            String shortMsg, String longMsg, String stackTrace) {
11214        app.crashing = true;
11215        app.crashingReport = generateProcessError(app,
11216                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11217        startAppProblemLocked(app);
11218        app.stopFreezingAllLocked();
11219        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11220    }
11221
11222    private void makeAppNotRespondingLocked(ProcessRecord app,
11223            String activity, String shortMsg, String longMsg) {
11224        app.notResponding = true;
11225        app.notRespondingReport = generateProcessError(app,
11226                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11227                activity, shortMsg, longMsg, null);
11228        startAppProblemLocked(app);
11229        app.stopFreezingAllLocked();
11230    }
11231
11232    /**
11233     * Generate a process error record, suitable for attachment to a ProcessRecord.
11234     *
11235     * @param app The ProcessRecord in which the error occurred.
11236     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11237     *                      ActivityManager.AppErrorStateInfo
11238     * @param activity The activity associated with the crash, if known.
11239     * @param shortMsg Short message describing the crash.
11240     * @param longMsg Long message describing the crash.
11241     * @param stackTrace Full crash stack trace, may be null.
11242     *
11243     * @return Returns a fully-formed AppErrorStateInfo record.
11244     */
11245    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11246            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11247        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11248
11249        report.condition = condition;
11250        report.processName = app.processName;
11251        report.pid = app.pid;
11252        report.uid = app.info.uid;
11253        report.tag = activity;
11254        report.shortMsg = shortMsg;
11255        report.longMsg = longMsg;
11256        report.stackTrace = stackTrace;
11257
11258        return report;
11259    }
11260
11261    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11262        synchronized (this) {
11263            app.crashing = false;
11264            app.crashingReport = null;
11265            app.notResponding = false;
11266            app.notRespondingReport = null;
11267            if (app.anrDialog == fromDialog) {
11268                app.anrDialog = null;
11269            }
11270            if (app.waitDialog == fromDialog) {
11271                app.waitDialog = null;
11272            }
11273            if (app.pid > 0 && app.pid != MY_PID) {
11274                handleAppCrashLocked(app, null, null, null);
11275                app.kill("user request after error", true);
11276            }
11277        }
11278    }
11279
11280    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11281            String stackTrace) {
11282        long now = SystemClock.uptimeMillis();
11283
11284        Long crashTime;
11285        if (!app.isolated) {
11286            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11287        } else {
11288            crashTime = null;
11289        }
11290        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11291            // This process loses!
11292            Slog.w(TAG, "Process " + app.info.processName
11293                    + " has crashed too many times: killing!");
11294            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11295                    app.userId, app.info.processName, app.uid);
11296            mStackSupervisor.handleAppCrashLocked(app);
11297            if (!app.persistent) {
11298                // We don't want to start this process again until the user
11299                // explicitly does so...  but for persistent process, we really
11300                // need to keep it running.  If a persistent process is actually
11301                // repeatedly crashing, then badness for everyone.
11302                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11303                        app.info.processName);
11304                if (!app.isolated) {
11305                    // XXX We don't have a way to mark isolated processes
11306                    // as bad, since they don't have a peristent identity.
11307                    mBadProcesses.put(app.info.processName, app.uid,
11308                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11309                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11310                }
11311                app.bad = true;
11312                app.removed = true;
11313                // Don't let services in this process be restarted and potentially
11314                // annoy the user repeatedly.  Unless it is persistent, since those
11315                // processes run critical code.
11316                removeProcessLocked(app, false, false, "crash");
11317                mStackSupervisor.resumeTopActivitiesLocked();
11318                return false;
11319            }
11320            mStackSupervisor.resumeTopActivitiesLocked();
11321        } else {
11322            mStackSupervisor.finishTopRunningActivityLocked(app);
11323        }
11324
11325        // Bump up the crash count of any services currently running in the proc.
11326        for (int i=app.services.size()-1; i>=0; i--) {
11327            // Any services running in the application need to be placed
11328            // back in the pending list.
11329            ServiceRecord sr = app.services.valueAt(i);
11330            sr.crashCount++;
11331        }
11332
11333        // If the crashing process is what we consider to be the "home process" and it has been
11334        // replaced by a third-party app, clear the package preferred activities from packages
11335        // with a home activity running in the process to prevent a repeatedly crashing app
11336        // from blocking the user to manually clear the list.
11337        final ArrayList<ActivityRecord> activities = app.activities;
11338        if (app == mHomeProcess && activities.size() > 0
11339                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11340            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11341                final ActivityRecord r = activities.get(activityNdx);
11342                if (r.isHomeActivity()) {
11343                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11344                    try {
11345                        ActivityThread.getPackageManager()
11346                                .clearPackagePreferredActivities(r.packageName);
11347                    } catch (RemoteException c) {
11348                        // pm is in same process, this will never happen.
11349                    }
11350                }
11351            }
11352        }
11353
11354        if (!app.isolated) {
11355            // XXX Can't keep track of crash times for isolated processes,
11356            // because they don't have a perisistent identity.
11357            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11358        }
11359
11360        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11361        return true;
11362    }
11363
11364    void startAppProblemLocked(ProcessRecord app) {
11365        // If this app is not running under the current user, then we
11366        // can't give it a report button because that would require
11367        // launching the report UI under a different user.
11368        app.errorReportReceiver = null;
11369
11370        for (int userId : mCurrentProfileIds) {
11371            if (app.userId == userId) {
11372                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11373                        mContext, app.info.packageName, app.info.flags);
11374            }
11375        }
11376        skipCurrentReceiverLocked(app);
11377    }
11378
11379    void skipCurrentReceiverLocked(ProcessRecord app) {
11380        for (BroadcastQueue queue : mBroadcastQueues) {
11381            queue.skipCurrentReceiverLocked(app);
11382        }
11383    }
11384
11385    /**
11386     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11387     * The application process will exit immediately after this call returns.
11388     * @param app object of the crashing app, null for the system server
11389     * @param crashInfo describing the exception
11390     */
11391    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11392        ProcessRecord r = findAppProcess(app, "Crash");
11393        final String processName = app == null ? "system_server"
11394                : (r == null ? "unknown" : r.processName);
11395
11396        handleApplicationCrashInner("crash", r, processName, crashInfo);
11397    }
11398
11399    /* Native crash reporting uses this inner version because it needs to be somewhat
11400     * decoupled from the AM-managed cleanup lifecycle
11401     */
11402    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11403            ApplicationErrorReport.CrashInfo crashInfo) {
11404        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11405                UserHandle.getUserId(Binder.getCallingUid()), processName,
11406                r == null ? -1 : r.info.flags,
11407                crashInfo.exceptionClassName,
11408                crashInfo.exceptionMessage,
11409                crashInfo.throwFileName,
11410                crashInfo.throwLineNumber);
11411
11412        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11413
11414        crashApplication(r, crashInfo);
11415    }
11416
11417    public void handleApplicationStrictModeViolation(
11418            IBinder app,
11419            int violationMask,
11420            StrictMode.ViolationInfo info) {
11421        ProcessRecord r = findAppProcess(app, "StrictMode");
11422        if (r == null) {
11423            return;
11424        }
11425
11426        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11427            Integer stackFingerprint = info.hashCode();
11428            boolean logIt = true;
11429            synchronized (mAlreadyLoggedViolatedStacks) {
11430                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11431                    logIt = false;
11432                    // TODO: sub-sample into EventLog for these, with
11433                    // the info.durationMillis?  Then we'd get
11434                    // the relative pain numbers, without logging all
11435                    // the stack traces repeatedly.  We'd want to do
11436                    // likewise in the client code, which also does
11437                    // dup suppression, before the Binder call.
11438                } else {
11439                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11440                        mAlreadyLoggedViolatedStacks.clear();
11441                    }
11442                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11443                }
11444            }
11445            if (logIt) {
11446                logStrictModeViolationToDropBox(r, info);
11447            }
11448        }
11449
11450        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11451            AppErrorResult result = new AppErrorResult();
11452            synchronized (this) {
11453                final long origId = Binder.clearCallingIdentity();
11454
11455                Message msg = Message.obtain();
11456                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11457                HashMap<String, Object> data = new HashMap<String, Object>();
11458                data.put("result", result);
11459                data.put("app", r);
11460                data.put("violationMask", violationMask);
11461                data.put("info", info);
11462                msg.obj = data;
11463                mHandler.sendMessage(msg);
11464
11465                Binder.restoreCallingIdentity(origId);
11466            }
11467            int res = result.get();
11468            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11469        }
11470    }
11471
11472    // Depending on the policy in effect, there could be a bunch of
11473    // these in quick succession so we try to batch these together to
11474    // minimize disk writes, number of dropbox entries, and maximize
11475    // compression, by having more fewer, larger records.
11476    private void logStrictModeViolationToDropBox(
11477            ProcessRecord process,
11478            StrictMode.ViolationInfo info) {
11479        if (info == null) {
11480            return;
11481        }
11482        final boolean isSystemApp = process == null ||
11483                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11484                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11485        final String processName = process == null ? "unknown" : process.processName;
11486        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11487        final DropBoxManager dbox = (DropBoxManager)
11488                mContext.getSystemService(Context.DROPBOX_SERVICE);
11489
11490        // Exit early if the dropbox isn't configured to accept this report type.
11491        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11492
11493        boolean bufferWasEmpty;
11494        boolean needsFlush;
11495        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11496        synchronized (sb) {
11497            bufferWasEmpty = sb.length() == 0;
11498            appendDropBoxProcessHeaders(process, processName, sb);
11499            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11500            sb.append("System-App: ").append(isSystemApp).append("\n");
11501            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11502            if (info.violationNumThisLoop != 0) {
11503                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11504            }
11505            if (info.numAnimationsRunning != 0) {
11506                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11507            }
11508            if (info.broadcastIntentAction != null) {
11509                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11510            }
11511            if (info.durationMillis != -1) {
11512                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11513            }
11514            if (info.numInstances != -1) {
11515                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11516            }
11517            if (info.tags != null) {
11518                for (String tag : info.tags) {
11519                    sb.append("Span-Tag: ").append(tag).append("\n");
11520                }
11521            }
11522            sb.append("\n");
11523            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11524                sb.append(info.crashInfo.stackTrace);
11525            }
11526            sb.append("\n");
11527
11528            // Only buffer up to ~64k.  Various logging bits truncate
11529            // things at 128k.
11530            needsFlush = (sb.length() > 64 * 1024);
11531        }
11532
11533        // Flush immediately if the buffer's grown too large, or this
11534        // is a non-system app.  Non-system apps are isolated with a
11535        // different tag & policy and not batched.
11536        //
11537        // Batching is useful during internal testing with
11538        // StrictMode settings turned up high.  Without batching,
11539        // thousands of separate files could be created on boot.
11540        if (!isSystemApp || needsFlush) {
11541            new Thread("Error dump: " + dropboxTag) {
11542                @Override
11543                public void run() {
11544                    String report;
11545                    synchronized (sb) {
11546                        report = sb.toString();
11547                        sb.delete(0, sb.length());
11548                        sb.trimToSize();
11549                    }
11550                    if (report.length() != 0) {
11551                        dbox.addText(dropboxTag, report);
11552                    }
11553                }
11554            }.start();
11555            return;
11556        }
11557
11558        // System app batching:
11559        if (!bufferWasEmpty) {
11560            // An existing dropbox-writing thread is outstanding, so
11561            // we don't need to start it up.  The existing thread will
11562            // catch the buffer appends we just did.
11563            return;
11564        }
11565
11566        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11567        // (After this point, we shouldn't access AMS internal data structures.)
11568        new Thread("Error dump: " + dropboxTag) {
11569            @Override
11570            public void run() {
11571                // 5 second sleep to let stacks arrive and be batched together
11572                try {
11573                    Thread.sleep(5000);  // 5 seconds
11574                } catch (InterruptedException e) {}
11575
11576                String errorReport;
11577                synchronized (mStrictModeBuffer) {
11578                    errorReport = mStrictModeBuffer.toString();
11579                    if (errorReport.length() == 0) {
11580                        return;
11581                    }
11582                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11583                    mStrictModeBuffer.trimToSize();
11584                }
11585                dbox.addText(dropboxTag, errorReport);
11586            }
11587        }.start();
11588    }
11589
11590    /**
11591     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11592     * @param app object of the crashing app, null for the system server
11593     * @param tag reported by the caller
11594     * @param system whether this wtf is coming from the system
11595     * @param crashInfo describing the context of the error
11596     * @return true if the process should exit immediately (WTF is fatal)
11597     */
11598    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11599            final ApplicationErrorReport.CrashInfo crashInfo) {
11600        final ProcessRecord r = findAppProcess(app, "WTF");
11601        final String processName = app == null ? "system_server"
11602                : (r == null ? "unknown" : r.processName);
11603
11604        EventLog.writeEvent(EventLogTags.AM_WTF,
11605                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11606                processName,
11607                r == null ? -1 : r.info.flags,
11608                tag, crashInfo.exceptionMessage);
11609
11610        if (system) {
11611            // If this is coming from the system, we could very well have low-level
11612            // system locks held, so we want to do this all asynchronously.  And we
11613            // never want this to become fatal, so there is that too.
11614            mHandler.post(new Runnable() {
11615                @Override public void run() {
11616                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11617                            crashInfo);
11618                }
11619            });
11620            return false;
11621        }
11622
11623        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11624
11625        if (r != null && r.pid != Process.myPid() &&
11626                Settings.Global.getInt(mContext.getContentResolver(),
11627                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11628            crashApplication(r, crashInfo);
11629            return true;
11630        } else {
11631            return false;
11632        }
11633    }
11634
11635    /**
11636     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11637     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11638     */
11639    private ProcessRecord findAppProcess(IBinder app, String reason) {
11640        if (app == null) {
11641            return null;
11642        }
11643
11644        synchronized (this) {
11645            final int NP = mProcessNames.getMap().size();
11646            for (int ip=0; ip<NP; ip++) {
11647                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11648                final int NA = apps.size();
11649                for (int ia=0; ia<NA; ia++) {
11650                    ProcessRecord p = apps.valueAt(ia);
11651                    if (p.thread != null && p.thread.asBinder() == app) {
11652                        return p;
11653                    }
11654                }
11655            }
11656
11657            Slog.w(TAG, "Can't find mystery application for " + reason
11658                    + " from pid=" + Binder.getCallingPid()
11659                    + " uid=" + Binder.getCallingUid() + ": " + app);
11660            return null;
11661        }
11662    }
11663
11664    /**
11665     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11666     * to append various headers to the dropbox log text.
11667     */
11668    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11669            StringBuilder sb) {
11670        // Watchdog thread ends up invoking this function (with
11671        // a null ProcessRecord) to add the stack file to dropbox.
11672        // Do not acquire a lock on this (am) in such cases, as it
11673        // could cause a potential deadlock, if and when watchdog
11674        // is invoked due to unavailability of lock on am and it
11675        // would prevent watchdog from killing system_server.
11676        if (process == null) {
11677            sb.append("Process: ").append(processName).append("\n");
11678            return;
11679        }
11680        // Note: ProcessRecord 'process' is guarded by the service
11681        // instance.  (notably process.pkgList, which could otherwise change
11682        // concurrently during execution of this method)
11683        synchronized (this) {
11684            sb.append("Process: ").append(processName).append("\n");
11685            int flags = process.info.flags;
11686            IPackageManager pm = AppGlobals.getPackageManager();
11687            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11688            for (int ip=0; ip<process.pkgList.size(); ip++) {
11689                String pkg = process.pkgList.keyAt(ip);
11690                sb.append("Package: ").append(pkg);
11691                try {
11692                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11693                    if (pi != null) {
11694                        sb.append(" v").append(pi.versionCode);
11695                        if (pi.versionName != null) {
11696                            sb.append(" (").append(pi.versionName).append(")");
11697                        }
11698                    }
11699                } catch (RemoteException e) {
11700                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11701                }
11702                sb.append("\n");
11703            }
11704        }
11705    }
11706
11707    private static String processClass(ProcessRecord process) {
11708        if (process == null || process.pid == MY_PID) {
11709            return "system_server";
11710        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11711            return "system_app";
11712        } else {
11713            return "data_app";
11714        }
11715    }
11716
11717    /**
11718     * Write a description of an error (crash, WTF, ANR) to the drop box.
11719     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11720     * @param process which caused the error, null means the system server
11721     * @param activity which triggered the error, null if unknown
11722     * @param parent activity related to the error, null if unknown
11723     * @param subject line related to the error, null if absent
11724     * @param report in long form describing the error, null if absent
11725     * @param logFile to include in the report, null if none
11726     * @param crashInfo giving an application stack trace, null if absent
11727     */
11728    public void addErrorToDropBox(String eventType,
11729            ProcessRecord process, String processName, ActivityRecord activity,
11730            ActivityRecord parent, String subject,
11731            final String report, final File logFile,
11732            final ApplicationErrorReport.CrashInfo crashInfo) {
11733        // NOTE -- this must never acquire the ActivityManagerService lock,
11734        // otherwise the watchdog may be prevented from resetting the system.
11735
11736        final String dropboxTag = processClass(process) + "_" + eventType;
11737        final DropBoxManager dbox = (DropBoxManager)
11738                mContext.getSystemService(Context.DROPBOX_SERVICE);
11739
11740        // Exit early if the dropbox isn't configured to accept this report type.
11741        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11742
11743        final StringBuilder sb = new StringBuilder(1024);
11744        appendDropBoxProcessHeaders(process, processName, sb);
11745        if (activity != null) {
11746            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11747        }
11748        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11749            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11750        }
11751        if (parent != null && parent != activity) {
11752            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11753        }
11754        if (subject != null) {
11755            sb.append("Subject: ").append(subject).append("\n");
11756        }
11757        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11758        if (Debug.isDebuggerConnected()) {
11759            sb.append("Debugger: Connected\n");
11760        }
11761        sb.append("\n");
11762
11763        // Do the rest in a worker thread to avoid blocking the caller on I/O
11764        // (After this point, we shouldn't access AMS internal data structures.)
11765        Thread worker = new Thread("Error dump: " + dropboxTag) {
11766            @Override
11767            public void run() {
11768                if (report != null) {
11769                    sb.append(report);
11770                }
11771                if (logFile != null) {
11772                    try {
11773                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11774                                    "\n\n[[TRUNCATED]]"));
11775                    } catch (IOException e) {
11776                        Slog.e(TAG, "Error reading " + logFile, e);
11777                    }
11778                }
11779                if (crashInfo != null && crashInfo.stackTrace != null) {
11780                    sb.append(crashInfo.stackTrace);
11781                }
11782
11783                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11784                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11785                if (lines > 0) {
11786                    sb.append("\n");
11787
11788                    // Merge several logcat streams, and take the last N lines
11789                    InputStreamReader input = null;
11790                    try {
11791                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11792                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11793                                "-b", "crash",
11794                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11795
11796                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11797                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11798                        input = new InputStreamReader(logcat.getInputStream());
11799
11800                        int num;
11801                        char[] buf = new char[8192];
11802                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11803                    } catch (IOException e) {
11804                        Slog.e(TAG, "Error running logcat", e);
11805                    } finally {
11806                        if (input != null) try { input.close(); } catch (IOException e) {}
11807                    }
11808                }
11809
11810                dbox.addText(dropboxTag, sb.toString());
11811            }
11812        };
11813
11814        if (process == null) {
11815            // If process is null, we are being called from some internal code
11816            // and may be about to die -- run this synchronously.
11817            worker.run();
11818        } else {
11819            worker.start();
11820        }
11821    }
11822
11823    /**
11824     * Bring up the "unexpected error" dialog box for a crashing app.
11825     * Deal with edge cases (intercepts from instrumented applications,
11826     * ActivityController, error intent receivers, that sort of thing).
11827     * @param r the application crashing
11828     * @param crashInfo describing the failure
11829     */
11830    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11831        long timeMillis = System.currentTimeMillis();
11832        String shortMsg = crashInfo.exceptionClassName;
11833        String longMsg = crashInfo.exceptionMessage;
11834        String stackTrace = crashInfo.stackTrace;
11835        if (shortMsg != null && longMsg != null) {
11836            longMsg = shortMsg + ": " + longMsg;
11837        } else if (shortMsg != null) {
11838            longMsg = shortMsg;
11839        }
11840
11841        AppErrorResult result = new AppErrorResult();
11842        synchronized (this) {
11843            if (mController != null) {
11844                try {
11845                    String name = r != null ? r.processName : null;
11846                    int pid = r != null ? r.pid : Binder.getCallingPid();
11847                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11848                    if (!mController.appCrashed(name, pid,
11849                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11850                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11851                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11852                            Slog.w(TAG, "Skip killing native crashed app " + name
11853                                    + "(" + pid + ") during testing");
11854                        } else {
11855                            Slog.w(TAG, "Force-killing crashed app " + name
11856                                    + " at watcher's request");
11857                            if (r != null) {
11858                                r.kill("crash", true);
11859                            } else {
11860                                // Huh.
11861                                Process.killProcess(pid);
11862                                Process.killProcessGroup(uid, pid);
11863                            }
11864                        }
11865                        return;
11866                    }
11867                } catch (RemoteException e) {
11868                    mController = null;
11869                    Watchdog.getInstance().setActivityController(null);
11870                }
11871            }
11872
11873            final long origId = Binder.clearCallingIdentity();
11874
11875            // If this process is running instrumentation, finish it.
11876            if (r != null && r.instrumentationClass != null) {
11877                Slog.w(TAG, "Error in app " + r.processName
11878                      + " running instrumentation " + r.instrumentationClass + ":");
11879                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11880                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11881                Bundle info = new Bundle();
11882                info.putString("shortMsg", shortMsg);
11883                info.putString("longMsg", longMsg);
11884                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11885                Binder.restoreCallingIdentity(origId);
11886                return;
11887            }
11888
11889            // If we can't identify the process or it's already exceeded its crash quota,
11890            // quit right away without showing a crash dialog.
11891            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11892                Binder.restoreCallingIdentity(origId);
11893                return;
11894            }
11895
11896            Message msg = Message.obtain();
11897            msg.what = SHOW_ERROR_MSG;
11898            HashMap data = new HashMap();
11899            data.put("result", result);
11900            data.put("app", r);
11901            msg.obj = data;
11902            mHandler.sendMessage(msg);
11903
11904            Binder.restoreCallingIdentity(origId);
11905        }
11906
11907        int res = result.get();
11908
11909        Intent appErrorIntent = null;
11910        synchronized (this) {
11911            if (r != null && !r.isolated) {
11912                // XXX Can't keep track of crash time for isolated processes,
11913                // since they don't have a persistent identity.
11914                mProcessCrashTimes.put(r.info.processName, r.uid,
11915                        SystemClock.uptimeMillis());
11916            }
11917            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11918                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11919            }
11920        }
11921
11922        if (appErrorIntent != null) {
11923            try {
11924                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11925            } catch (ActivityNotFoundException e) {
11926                Slog.w(TAG, "bug report receiver dissappeared", e);
11927            }
11928        }
11929    }
11930
11931    Intent createAppErrorIntentLocked(ProcessRecord r,
11932            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11933        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11934        if (report == null) {
11935            return null;
11936        }
11937        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11938        result.setComponent(r.errorReportReceiver);
11939        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11940        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11941        return result;
11942    }
11943
11944    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11945            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11946        if (r.errorReportReceiver == null) {
11947            return null;
11948        }
11949
11950        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11951            return null;
11952        }
11953
11954        ApplicationErrorReport report = new ApplicationErrorReport();
11955        report.packageName = r.info.packageName;
11956        report.installerPackageName = r.errorReportReceiver.getPackageName();
11957        report.processName = r.processName;
11958        report.time = timeMillis;
11959        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11960
11961        if (r.crashing || r.forceCrashReport) {
11962            report.type = ApplicationErrorReport.TYPE_CRASH;
11963            report.crashInfo = crashInfo;
11964        } else if (r.notResponding) {
11965            report.type = ApplicationErrorReport.TYPE_ANR;
11966            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11967
11968            report.anrInfo.activity = r.notRespondingReport.tag;
11969            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11970            report.anrInfo.info = r.notRespondingReport.longMsg;
11971        }
11972
11973        return report;
11974    }
11975
11976    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11977        enforceNotIsolatedCaller("getProcessesInErrorState");
11978        // assume our apps are happy - lazy create the list
11979        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11980
11981        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11982                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11983        int userId = UserHandle.getUserId(Binder.getCallingUid());
11984
11985        synchronized (this) {
11986
11987            // iterate across all processes
11988            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11989                ProcessRecord app = mLruProcesses.get(i);
11990                if (!allUsers && app.userId != userId) {
11991                    continue;
11992                }
11993                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11994                    // This one's in trouble, so we'll generate a report for it
11995                    // crashes are higher priority (in case there's a crash *and* an anr)
11996                    ActivityManager.ProcessErrorStateInfo report = null;
11997                    if (app.crashing) {
11998                        report = app.crashingReport;
11999                    } else if (app.notResponding) {
12000                        report = app.notRespondingReport;
12001                    }
12002
12003                    if (report != null) {
12004                        if (errList == null) {
12005                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12006                        }
12007                        errList.add(report);
12008                    } else {
12009                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12010                                " crashing = " + app.crashing +
12011                                " notResponding = " + app.notResponding);
12012                    }
12013                }
12014            }
12015        }
12016
12017        return errList;
12018    }
12019
12020    static int procStateToImportance(int procState, int memAdj,
12021            ActivityManager.RunningAppProcessInfo currApp) {
12022        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12023        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12024            currApp.lru = memAdj;
12025        } else {
12026            currApp.lru = 0;
12027        }
12028        return imp;
12029    }
12030
12031    private void fillInProcMemInfo(ProcessRecord app,
12032            ActivityManager.RunningAppProcessInfo outInfo) {
12033        outInfo.pid = app.pid;
12034        outInfo.uid = app.info.uid;
12035        if (mHeavyWeightProcess == app) {
12036            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12037        }
12038        if (app.persistent) {
12039            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12040        }
12041        if (app.activities.size() > 0) {
12042            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12043        }
12044        outInfo.lastTrimLevel = app.trimMemoryLevel;
12045        int adj = app.curAdj;
12046        int procState = app.curProcState;
12047        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12048        outInfo.importanceReasonCode = app.adjTypeCode;
12049        outInfo.processState = app.curProcState;
12050    }
12051
12052    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12053        enforceNotIsolatedCaller("getRunningAppProcesses");
12054        // Lazy instantiation of list
12055        List<ActivityManager.RunningAppProcessInfo> runList = null;
12056        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12057                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12058        int userId = UserHandle.getUserId(Binder.getCallingUid());
12059        synchronized (this) {
12060            // Iterate across all processes
12061            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12062                ProcessRecord app = mLruProcesses.get(i);
12063                if (!allUsers && app.userId != userId) {
12064                    continue;
12065                }
12066                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12067                    // Generate process state info for running application
12068                    ActivityManager.RunningAppProcessInfo currApp =
12069                        new ActivityManager.RunningAppProcessInfo(app.processName,
12070                                app.pid, app.getPackageList());
12071                    fillInProcMemInfo(app, currApp);
12072                    if (app.adjSource instanceof ProcessRecord) {
12073                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12074                        currApp.importanceReasonImportance =
12075                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12076                                        app.adjSourceProcState);
12077                    } else if (app.adjSource instanceof ActivityRecord) {
12078                        ActivityRecord r = (ActivityRecord)app.adjSource;
12079                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12080                    }
12081                    if (app.adjTarget instanceof ComponentName) {
12082                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12083                    }
12084                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12085                    //        + " lru=" + currApp.lru);
12086                    if (runList == null) {
12087                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12088                    }
12089                    runList.add(currApp);
12090                }
12091            }
12092        }
12093        return runList;
12094    }
12095
12096    public List<ApplicationInfo> getRunningExternalApplications() {
12097        enforceNotIsolatedCaller("getRunningExternalApplications");
12098        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12099        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12100        if (runningApps != null && runningApps.size() > 0) {
12101            Set<String> extList = new HashSet<String>();
12102            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12103                if (app.pkgList != null) {
12104                    for (String pkg : app.pkgList) {
12105                        extList.add(pkg);
12106                    }
12107                }
12108            }
12109            IPackageManager pm = AppGlobals.getPackageManager();
12110            for (String pkg : extList) {
12111                try {
12112                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12113                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12114                        retList.add(info);
12115                    }
12116                } catch (RemoteException e) {
12117                }
12118            }
12119        }
12120        return retList;
12121    }
12122
12123    @Override
12124    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12125        enforceNotIsolatedCaller("getMyMemoryState");
12126        synchronized (this) {
12127            ProcessRecord proc;
12128            synchronized (mPidsSelfLocked) {
12129                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12130            }
12131            fillInProcMemInfo(proc, outInfo);
12132        }
12133    }
12134
12135    @Override
12136    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12137        if (checkCallingPermission(android.Manifest.permission.DUMP)
12138                != PackageManager.PERMISSION_GRANTED) {
12139            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12140                    + Binder.getCallingPid()
12141                    + ", uid=" + Binder.getCallingUid()
12142                    + " without permission "
12143                    + android.Manifest.permission.DUMP);
12144            return;
12145        }
12146
12147        boolean dumpAll = false;
12148        boolean dumpClient = false;
12149        String dumpPackage = null;
12150
12151        int opti = 0;
12152        while (opti < args.length) {
12153            String opt = args[opti];
12154            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12155                break;
12156            }
12157            opti++;
12158            if ("-a".equals(opt)) {
12159                dumpAll = true;
12160            } else if ("-c".equals(opt)) {
12161                dumpClient = true;
12162            } else if ("-h".equals(opt)) {
12163                pw.println("Activity manager dump options:");
12164                pw.println("  [-a] [-c] [-h] [cmd] ...");
12165                pw.println("  cmd may be one of:");
12166                pw.println("    a[ctivities]: activity stack state");
12167                pw.println("    r[recents]: recent activities state");
12168                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12169                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12170                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12171                pw.println("    o[om]: out of memory management");
12172                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12173                pw.println("    provider [COMP_SPEC]: provider client-side state");
12174                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12175                pw.println("    service [COMP_SPEC]: service client-side state");
12176                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12177                pw.println("    all: dump all activities");
12178                pw.println("    top: dump the top activity");
12179                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12180                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12181                pw.println("    a partial substring in a component name, a");
12182                pw.println("    hex object identifier.");
12183                pw.println("  -a: include all available server state.");
12184                pw.println("  -c: include client state.");
12185                return;
12186            } else {
12187                pw.println("Unknown argument: " + opt + "; use -h for help");
12188            }
12189        }
12190
12191        long origId = Binder.clearCallingIdentity();
12192        boolean more = false;
12193        // Is the caller requesting to dump a particular piece of data?
12194        if (opti < args.length) {
12195            String cmd = args[opti];
12196            opti++;
12197            if ("activities".equals(cmd) || "a".equals(cmd)) {
12198                synchronized (this) {
12199                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12200                }
12201            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12202                synchronized (this) {
12203                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12204                }
12205            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12206                String[] newArgs;
12207                String name;
12208                if (opti >= args.length) {
12209                    name = null;
12210                    newArgs = EMPTY_STRING_ARRAY;
12211                } else {
12212                    name = args[opti];
12213                    opti++;
12214                    newArgs = new String[args.length - opti];
12215                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12216                            args.length - opti);
12217                }
12218                synchronized (this) {
12219                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12220                }
12221            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12222                String[] newArgs;
12223                String name;
12224                if (opti >= args.length) {
12225                    name = null;
12226                    newArgs = EMPTY_STRING_ARRAY;
12227                } else {
12228                    name = args[opti];
12229                    opti++;
12230                    newArgs = new String[args.length - opti];
12231                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12232                            args.length - opti);
12233                }
12234                synchronized (this) {
12235                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12236                }
12237            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12238                String[] newArgs;
12239                String name;
12240                if (opti >= args.length) {
12241                    name = null;
12242                    newArgs = EMPTY_STRING_ARRAY;
12243                } else {
12244                    name = args[opti];
12245                    opti++;
12246                    newArgs = new String[args.length - opti];
12247                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12248                            args.length - opti);
12249                }
12250                synchronized (this) {
12251                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12252                }
12253            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12254                synchronized (this) {
12255                    dumpOomLocked(fd, pw, args, opti, true);
12256                }
12257            } else if ("provider".equals(cmd)) {
12258                String[] newArgs;
12259                String name;
12260                if (opti >= args.length) {
12261                    name = null;
12262                    newArgs = EMPTY_STRING_ARRAY;
12263                } else {
12264                    name = args[opti];
12265                    opti++;
12266                    newArgs = new String[args.length - opti];
12267                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12268                }
12269                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12270                    pw.println("No providers match: " + name);
12271                    pw.println("Use -h for help.");
12272                }
12273            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12274                synchronized (this) {
12275                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12276                }
12277            } else if ("service".equals(cmd)) {
12278                String[] newArgs;
12279                String name;
12280                if (opti >= args.length) {
12281                    name = null;
12282                    newArgs = EMPTY_STRING_ARRAY;
12283                } else {
12284                    name = args[opti];
12285                    opti++;
12286                    newArgs = new String[args.length - opti];
12287                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12288                            args.length - opti);
12289                }
12290                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12291                    pw.println("No services match: " + name);
12292                    pw.println("Use -h for help.");
12293                }
12294            } else if ("package".equals(cmd)) {
12295                String[] newArgs;
12296                if (opti >= args.length) {
12297                    pw.println("package: no package name specified");
12298                    pw.println("Use -h for help.");
12299                } else {
12300                    dumpPackage = args[opti];
12301                    opti++;
12302                    newArgs = new String[args.length - opti];
12303                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12304                            args.length - opti);
12305                    args = newArgs;
12306                    opti = 0;
12307                    more = true;
12308                }
12309            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12310                synchronized (this) {
12311                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12312                }
12313            } else {
12314                // Dumping a single activity?
12315                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12316                    pw.println("Bad activity command, or no activities match: " + cmd);
12317                    pw.println("Use -h for help.");
12318                }
12319            }
12320            if (!more) {
12321                Binder.restoreCallingIdentity(origId);
12322                return;
12323            }
12324        }
12325
12326        // No piece of data specified, dump everything.
12327        synchronized (this) {
12328            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12329            pw.println();
12330            if (dumpAll) {
12331                pw.println("-------------------------------------------------------------------------------");
12332            }
12333            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12334            pw.println();
12335            if (dumpAll) {
12336                pw.println("-------------------------------------------------------------------------------");
12337            }
12338            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12339            pw.println();
12340            if (dumpAll) {
12341                pw.println("-------------------------------------------------------------------------------");
12342            }
12343            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12344            pw.println();
12345            if (dumpAll) {
12346                pw.println("-------------------------------------------------------------------------------");
12347            }
12348            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12349            pw.println();
12350            if (dumpAll) {
12351                pw.println("-------------------------------------------------------------------------------");
12352            }
12353            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12354            pw.println();
12355            if (dumpAll) {
12356                pw.println("-------------------------------------------------------------------------------");
12357            }
12358            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12359        }
12360        Binder.restoreCallingIdentity(origId);
12361    }
12362
12363    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12364            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12365        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12366
12367        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12368                dumpPackage);
12369        boolean needSep = printedAnything;
12370
12371        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12372                dumpPackage, needSep, "  mFocusedActivity: ");
12373        if (printed) {
12374            printedAnything = true;
12375            needSep = false;
12376        }
12377
12378        if (dumpPackage == null) {
12379            if (needSep) {
12380                pw.println();
12381            }
12382            needSep = true;
12383            printedAnything = true;
12384            mStackSupervisor.dump(pw, "  ");
12385        }
12386
12387        if (!printedAnything) {
12388            pw.println("  (nothing)");
12389        }
12390    }
12391
12392    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12393            int opti, boolean dumpAll, String dumpPackage) {
12394        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12395
12396        boolean printedAnything = false;
12397
12398        if (mRecentTasks.size() > 0) {
12399            boolean printedHeader = false;
12400
12401            final int N = mRecentTasks.size();
12402            for (int i=0; i<N; i++) {
12403                TaskRecord tr = mRecentTasks.get(i);
12404                if (dumpPackage != null) {
12405                    if (tr.realActivity == null ||
12406                            !dumpPackage.equals(tr.realActivity)) {
12407                        continue;
12408                    }
12409                }
12410                if (!printedHeader) {
12411                    pw.println("  Recent tasks:");
12412                    printedHeader = true;
12413                    printedAnything = true;
12414                }
12415                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12416                        pw.println(tr);
12417                if (dumpAll) {
12418                    mRecentTasks.get(i).dump(pw, "    ");
12419                }
12420            }
12421        }
12422
12423        if (!printedAnything) {
12424            pw.println("  (nothing)");
12425        }
12426    }
12427
12428    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12429            int opti, boolean dumpAll, String dumpPackage) {
12430        boolean needSep = false;
12431        boolean printedAnything = false;
12432        int numPers = 0;
12433
12434        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12435
12436        if (dumpAll) {
12437            final int NP = mProcessNames.getMap().size();
12438            for (int ip=0; ip<NP; ip++) {
12439                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12440                final int NA = procs.size();
12441                for (int ia=0; ia<NA; ia++) {
12442                    ProcessRecord r = procs.valueAt(ia);
12443                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12444                        continue;
12445                    }
12446                    if (!needSep) {
12447                        pw.println("  All known processes:");
12448                        needSep = true;
12449                        printedAnything = true;
12450                    }
12451                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12452                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12453                        pw.print(" "); pw.println(r);
12454                    r.dump(pw, "    ");
12455                    if (r.persistent) {
12456                        numPers++;
12457                    }
12458                }
12459            }
12460        }
12461
12462        if (mIsolatedProcesses.size() > 0) {
12463            boolean printed = false;
12464            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12465                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12466                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12467                    continue;
12468                }
12469                if (!printed) {
12470                    if (needSep) {
12471                        pw.println();
12472                    }
12473                    pw.println("  Isolated process list (sorted by uid):");
12474                    printedAnything = true;
12475                    printed = true;
12476                    needSep = true;
12477                }
12478                pw.println(String.format("%sIsolated #%2d: %s",
12479                        "    ", i, r.toString()));
12480            }
12481        }
12482
12483        if (mLruProcesses.size() > 0) {
12484            if (needSep) {
12485                pw.println();
12486            }
12487            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12488                    pw.print(" total, non-act at ");
12489                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12490                    pw.print(", non-svc at ");
12491                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12492                    pw.println("):");
12493            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12494            needSep = true;
12495            printedAnything = true;
12496        }
12497
12498        if (dumpAll || dumpPackage != null) {
12499            synchronized (mPidsSelfLocked) {
12500                boolean printed = false;
12501                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12502                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12503                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12504                        continue;
12505                    }
12506                    if (!printed) {
12507                        if (needSep) pw.println();
12508                        needSep = true;
12509                        pw.println("  PID mappings:");
12510                        printed = true;
12511                        printedAnything = true;
12512                    }
12513                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12514                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12515                }
12516            }
12517        }
12518
12519        if (mForegroundProcesses.size() > 0) {
12520            synchronized (mPidsSelfLocked) {
12521                boolean printed = false;
12522                for (int i=0; i<mForegroundProcesses.size(); i++) {
12523                    ProcessRecord r = mPidsSelfLocked.get(
12524                            mForegroundProcesses.valueAt(i).pid);
12525                    if (dumpPackage != null && (r == null
12526                            || !r.pkgList.containsKey(dumpPackage))) {
12527                        continue;
12528                    }
12529                    if (!printed) {
12530                        if (needSep) pw.println();
12531                        needSep = true;
12532                        pw.println("  Foreground Processes:");
12533                        printed = true;
12534                        printedAnything = true;
12535                    }
12536                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12537                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12538                }
12539            }
12540        }
12541
12542        if (mPersistentStartingProcesses.size() > 0) {
12543            if (needSep) pw.println();
12544            needSep = true;
12545            printedAnything = true;
12546            pw.println("  Persisent processes that are starting:");
12547            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12548                    "Starting Norm", "Restarting PERS", dumpPackage);
12549        }
12550
12551        if (mRemovedProcesses.size() > 0) {
12552            if (needSep) pw.println();
12553            needSep = true;
12554            printedAnything = true;
12555            pw.println("  Processes that are being removed:");
12556            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12557                    "Removed Norm", "Removed PERS", dumpPackage);
12558        }
12559
12560        if (mProcessesOnHold.size() > 0) {
12561            if (needSep) pw.println();
12562            needSep = true;
12563            printedAnything = true;
12564            pw.println("  Processes that are on old until the system is ready:");
12565            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12566                    "OnHold Norm", "OnHold PERS", dumpPackage);
12567        }
12568
12569        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12570
12571        if (mProcessCrashTimes.getMap().size() > 0) {
12572            boolean printed = false;
12573            long now = SystemClock.uptimeMillis();
12574            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12575            final int NP = pmap.size();
12576            for (int ip=0; ip<NP; ip++) {
12577                String pname = pmap.keyAt(ip);
12578                SparseArray<Long> uids = pmap.valueAt(ip);
12579                final int N = uids.size();
12580                for (int i=0; i<N; i++) {
12581                    int puid = uids.keyAt(i);
12582                    ProcessRecord r = mProcessNames.get(pname, puid);
12583                    if (dumpPackage != null && (r == null
12584                            || !r.pkgList.containsKey(dumpPackage))) {
12585                        continue;
12586                    }
12587                    if (!printed) {
12588                        if (needSep) pw.println();
12589                        needSep = true;
12590                        pw.println("  Time since processes crashed:");
12591                        printed = true;
12592                        printedAnything = true;
12593                    }
12594                    pw.print("    Process "); pw.print(pname);
12595                            pw.print(" uid "); pw.print(puid);
12596                            pw.print(": last crashed ");
12597                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12598                            pw.println(" ago");
12599                }
12600            }
12601        }
12602
12603        if (mBadProcesses.getMap().size() > 0) {
12604            boolean printed = false;
12605            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12606            final int NP = pmap.size();
12607            for (int ip=0; ip<NP; ip++) {
12608                String pname = pmap.keyAt(ip);
12609                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12610                final int N = uids.size();
12611                for (int i=0; i<N; i++) {
12612                    int puid = uids.keyAt(i);
12613                    ProcessRecord r = mProcessNames.get(pname, puid);
12614                    if (dumpPackage != null && (r == null
12615                            || !r.pkgList.containsKey(dumpPackage))) {
12616                        continue;
12617                    }
12618                    if (!printed) {
12619                        if (needSep) pw.println();
12620                        needSep = true;
12621                        pw.println("  Bad processes:");
12622                        printedAnything = true;
12623                    }
12624                    BadProcessInfo info = uids.valueAt(i);
12625                    pw.print("    Bad process "); pw.print(pname);
12626                            pw.print(" uid "); pw.print(puid);
12627                            pw.print(": crashed at time "); pw.println(info.time);
12628                    if (info.shortMsg != null) {
12629                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12630                    }
12631                    if (info.longMsg != null) {
12632                        pw.print("      Long msg: "); pw.println(info.longMsg);
12633                    }
12634                    if (info.stack != null) {
12635                        pw.println("      Stack:");
12636                        int lastPos = 0;
12637                        for (int pos=0; pos<info.stack.length(); pos++) {
12638                            if (info.stack.charAt(pos) == '\n') {
12639                                pw.print("        ");
12640                                pw.write(info.stack, lastPos, pos-lastPos);
12641                                pw.println();
12642                                lastPos = pos+1;
12643                            }
12644                        }
12645                        if (lastPos < info.stack.length()) {
12646                            pw.print("        ");
12647                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12648                            pw.println();
12649                        }
12650                    }
12651                }
12652            }
12653        }
12654
12655        if (dumpPackage == null) {
12656            pw.println();
12657            needSep = false;
12658            pw.println("  mStartedUsers:");
12659            for (int i=0; i<mStartedUsers.size(); i++) {
12660                UserStartedState uss = mStartedUsers.valueAt(i);
12661                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12662                        pw.print(": "); uss.dump("", pw);
12663            }
12664            pw.print("  mStartedUserArray: [");
12665            for (int i=0; i<mStartedUserArray.length; i++) {
12666                if (i > 0) pw.print(", ");
12667                pw.print(mStartedUserArray[i]);
12668            }
12669            pw.println("]");
12670            pw.print("  mUserLru: [");
12671            for (int i=0; i<mUserLru.size(); i++) {
12672                if (i > 0) pw.print(", ");
12673                pw.print(mUserLru.get(i));
12674            }
12675            pw.println("]");
12676            if (dumpAll) {
12677                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12678            }
12679            synchronized (mUserProfileGroupIdsSelfLocked) {
12680                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12681                    pw.println("  mUserProfileGroupIds:");
12682                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12683                        pw.print("    User #");
12684                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12685                        pw.print(" -> profile #");
12686                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12687                    }
12688                }
12689            }
12690        }
12691        if (mHomeProcess != null && (dumpPackage == null
12692                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12693            if (needSep) {
12694                pw.println();
12695                needSep = false;
12696            }
12697            pw.println("  mHomeProcess: " + mHomeProcess);
12698        }
12699        if (mPreviousProcess != null && (dumpPackage == null
12700                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12701            if (needSep) {
12702                pw.println();
12703                needSep = false;
12704            }
12705            pw.println("  mPreviousProcess: " + mPreviousProcess);
12706        }
12707        if (dumpAll) {
12708            StringBuilder sb = new StringBuilder(128);
12709            sb.append("  mPreviousProcessVisibleTime: ");
12710            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12711            pw.println(sb);
12712        }
12713        if (mHeavyWeightProcess != null && (dumpPackage == null
12714                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12715            if (needSep) {
12716                pw.println();
12717                needSep = false;
12718            }
12719            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12720        }
12721        if (dumpPackage == null) {
12722            pw.println("  mConfiguration: " + mConfiguration);
12723        }
12724        if (dumpAll) {
12725            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12726            if (mCompatModePackages.getPackages().size() > 0) {
12727                boolean printed = false;
12728                for (Map.Entry<String, Integer> entry
12729                        : mCompatModePackages.getPackages().entrySet()) {
12730                    String pkg = entry.getKey();
12731                    int mode = entry.getValue();
12732                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12733                        continue;
12734                    }
12735                    if (!printed) {
12736                        pw.println("  mScreenCompatPackages:");
12737                        printed = true;
12738                    }
12739                    pw.print("    "); pw.print(pkg); pw.print(": ");
12740                            pw.print(mode); pw.println();
12741                }
12742            }
12743        }
12744        if (dumpPackage == null) {
12745            if (mSleeping || mWentToSleep || mLockScreenShown) {
12746                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12747                        + " mLockScreenShown " + mLockScreenShown);
12748            }
12749            if (mShuttingDown || mRunningVoice) {
12750                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12751            }
12752        }
12753        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12754                || mOrigWaitForDebugger) {
12755            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12756                    || dumpPackage.equals(mOrigDebugApp)) {
12757                if (needSep) {
12758                    pw.println();
12759                    needSep = false;
12760                }
12761                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12762                        + " mDebugTransient=" + mDebugTransient
12763                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12764            }
12765        }
12766        if (mOpenGlTraceApp != null) {
12767            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12768                if (needSep) {
12769                    pw.println();
12770                    needSep = false;
12771                }
12772                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12773            }
12774        }
12775        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12776                || mProfileFd != null) {
12777            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12778                if (needSep) {
12779                    pw.println();
12780                    needSep = false;
12781                }
12782                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12783                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12784                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12785                        + mAutoStopProfiler);
12786                pw.println("  mProfileType=" + mProfileType);
12787            }
12788        }
12789        if (dumpPackage == null) {
12790            if (mAlwaysFinishActivities || mController != null) {
12791                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12792                        + " mController=" + mController);
12793            }
12794            if (dumpAll) {
12795                pw.println("  Total persistent processes: " + numPers);
12796                pw.println("  mProcessesReady=" + mProcessesReady
12797                        + " mSystemReady=" + mSystemReady);
12798                pw.println("  mBooting=" + mBooting
12799                        + " mBooted=" + mBooted
12800                        + " mFactoryTest=" + mFactoryTest);
12801                pw.print("  mLastPowerCheckRealtime=");
12802                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12803                        pw.println("");
12804                pw.print("  mLastPowerCheckUptime=");
12805                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12806                        pw.println("");
12807                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12808                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12809                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12810                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12811                        + " (" + mLruProcesses.size() + " total)"
12812                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12813                        + " mNumServiceProcs=" + mNumServiceProcs
12814                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12815                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12816                        + " mLastMemoryLevel" + mLastMemoryLevel
12817                        + " mLastNumProcesses" + mLastNumProcesses);
12818                long now = SystemClock.uptimeMillis();
12819                pw.print("  mLastIdleTime=");
12820                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12821                        pw.print(" mLowRamSinceLastIdle=");
12822                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12823                        pw.println();
12824            }
12825        }
12826
12827        if (!printedAnything) {
12828            pw.println("  (nothing)");
12829        }
12830    }
12831
12832    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12833            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12834        if (mProcessesToGc.size() > 0) {
12835            boolean printed = false;
12836            long now = SystemClock.uptimeMillis();
12837            for (int i=0; i<mProcessesToGc.size(); i++) {
12838                ProcessRecord proc = mProcessesToGc.get(i);
12839                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12840                    continue;
12841                }
12842                if (!printed) {
12843                    if (needSep) pw.println();
12844                    needSep = true;
12845                    pw.println("  Processes that are waiting to GC:");
12846                    printed = true;
12847                }
12848                pw.print("    Process "); pw.println(proc);
12849                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12850                        pw.print(", last gced=");
12851                        pw.print(now-proc.lastRequestedGc);
12852                        pw.print(" ms ago, last lowMem=");
12853                        pw.print(now-proc.lastLowMemory);
12854                        pw.println(" ms ago");
12855
12856            }
12857        }
12858        return needSep;
12859    }
12860
12861    void printOomLevel(PrintWriter pw, String name, int adj) {
12862        pw.print("    ");
12863        if (adj >= 0) {
12864            pw.print(' ');
12865            if (adj < 10) pw.print(' ');
12866        } else {
12867            if (adj > -10) pw.print(' ');
12868        }
12869        pw.print(adj);
12870        pw.print(": ");
12871        pw.print(name);
12872        pw.print(" (");
12873        pw.print(mProcessList.getMemLevel(adj)/1024);
12874        pw.println(" kB)");
12875    }
12876
12877    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12878            int opti, boolean dumpAll) {
12879        boolean needSep = false;
12880
12881        if (mLruProcesses.size() > 0) {
12882            if (needSep) pw.println();
12883            needSep = true;
12884            pw.println("  OOM levels:");
12885            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12886            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12887            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12888            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12889            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12890            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12891            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12892            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12893            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12894            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12895            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12896            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12897            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12898
12899            if (needSep) pw.println();
12900            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12901                    pw.print(" total, non-act at ");
12902                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12903                    pw.print(", non-svc at ");
12904                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12905                    pw.println("):");
12906            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12907            needSep = true;
12908        }
12909
12910        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12911
12912        pw.println();
12913        pw.println("  mHomeProcess: " + mHomeProcess);
12914        pw.println("  mPreviousProcess: " + mPreviousProcess);
12915        if (mHeavyWeightProcess != null) {
12916            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12917        }
12918
12919        return true;
12920    }
12921
12922    /**
12923     * There are three ways to call this:
12924     *  - no provider specified: dump all the providers
12925     *  - a flattened component name that matched an existing provider was specified as the
12926     *    first arg: dump that one provider
12927     *  - the first arg isn't the flattened component name of an existing provider:
12928     *    dump all providers whose component contains the first arg as a substring
12929     */
12930    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12931            int opti, boolean dumpAll) {
12932        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12933    }
12934
12935    static class ItemMatcher {
12936        ArrayList<ComponentName> components;
12937        ArrayList<String> strings;
12938        ArrayList<Integer> objects;
12939        boolean all;
12940
12941        ItemMatcher() {
12942            all = true;
12943        }
12944
12945        void build(String name) {
12946            ComponentName componentName = ComponentName.unflattenFromString(name);
12947            if (componentName != null) {
12948                if (components == null) {
12949                    components = new ArrayList<ComponentName>();
12950                }
12951                components.add(componentName);
12952                all = false;
12953            } else {
12954                int objectId = 0;
12955                // Not a '/' separated full component name; maybe an object ID?
12956                try {
12957                    objectId = Integer.parseInt(name, 16);
12958                    if (objects == null) {
12959                        objects = new ArrayList<Integer>();
12960                    }
12961                    objects.add(objectId);
12962                    all = false;
12963                } catch (RuntimeException e) {
12964                    // Not an integer; just do string match.
12965                    if (strings == null) {
12966                        strings = new ArrayList<String>();
12967                    }
12968                    strings.add(name);
12969                    all = false;
12970                }
12971            }
12972        }
12973
12974        int build(String[] args, int opti) {
12975            for (; opti<args.length; opti++) {
12976                String name = args[opti];
12977                if ("--".equals(name)) {
12978                    return opti+1;
12979                }
12980                build(name);
12981            }
12982            return opti;
12983        }
12984
12985        boolean match(Object object, ComponentName comp) {
12986            if (all) {
12987                return true;
12988            }
12989            if (components != null) {
12990                for (int i=0; i<components.size(); i++) {
12991                    if (components.get(i).equals(comp)) {
12992                        return true;
12993                    }
12994                }
12995            }
12996            if (objects != null) {
12997                for (int i=0; i<objects.size(); i++) {
12998                    if (System.identityHashCode(object) == objects.get(i)) {
12999                        return true;
13000                    }
13001                }
13002            }
13003            if (strings != null) {
13004                String flat = comp.flattenToString();
13005                for (int i=0; i<strings.size(); i++) {
13006                    if (flat.contains(strings.get(i))) {
13007                        return true;
13008                    }
13009                }
13010            }
13011            return false;
13012        }
13013    }
13014
13015    /**
13016     * There are three things that cmd can be:
13017     *  - a flattened component name that matches an existing activity
13018     *  - the cmd arg isn't the flattened component name of an existing activity:
13019     *    dump all activity whose component contains the cmd as a substring
13020     *  - A hex number of the ActivityRecord object instance.
13021     */
13022    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13023            int opti, boolean dumpAll) {
13024        ArrayList<ActivityRecord> activities;
13025
13026        synchronized (this) {
13027            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13028        }
13029
13030        if (activities.size() <= 0) {
13031            return false;
13032        }
13033
13034        String[] newArgs = new String[args.length - opti];
13035        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13036
13037        TaskRecord lastTask = null;
13038        boolean needSep = false;
13039        for (int i=activities.size()-1; i>=0; i--) {
13040            ActivityRecord r = activities.get(i);
13041            if (needSep) {
13042                pw.println();
13043            }
13044            needSep = true;
13045            synchronized (this) {
13046                if (lastTask != r.task) {
13047                    lastTask = r.task;
13048                    pw.print("TASK "); pw.print(lastTask.affinity);
13049                            pw.print(" id="); pw.println(lastTask.taskId);
13050                    if (dumpAll) {
13051                        lastTask.dump(pw, "  ");
13052                    }
13053                }
13054            }
13055            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13056        }
13057        return true;
13058    }
13059
13060    /**
13061     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13062     * there is a thread associated with the activity.
13063     */
13064    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13065            final ActivityRecord r, String[] args, boolean dumpAll) {
13066        String innerPrefix = prefix + "  ";
13067        synchronized (this) {
13068            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13069                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13070                    pw.print(" pid=");
13071                    if (r.app != null) pw.println(r.app.pid);
13072                    else pw.println("(not running)");
13073            if (dumpAll) {
13074                r.dump(pw, innerPrefix);
13075            }
13076        }
13077        if (r.app != null && r.app.thread != null) {
13078            // flush anything that is already in the PrintWriter since the thread is going
13079            // to write to the file descriptor directly
13080            pw.flush();
13081            try {
13082                TransferPipe tp = new TransferPipe();
13083                try {
13084                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13085                            r.appToken, innerPrefix, args);
13086                    tp.go(fd);
13087                } finally {
13088                    tp.kill();
13089                }
13090            } catch (IOException e) {
13091                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13092            } catch (RemoteException e) {
13093                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13094            }
13095        }
13096    }
13097
13098    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13099            int opti, boolean dumpAll, String dumpPackage) {
13100        boolean needSep = false;
13101        boolean onlyHistory = false;
13102        boolean printedAnything = false;
13103
13104        if ("history".equals(dumpPackage)) {
13105            if (opti < args.length && "-s".equals(args[opti])) {
13106                dumpAll = false;
13107            }
13108            onlyHistory = true;
13109            dumpPackage = null;
13110        }
13111
13112        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13113        if (!onlyHistory && dumpAll) {
13114            if (mRegisteredReceivers.size() > 0) {
13115                boolean printed = false;
13116                Iterator it = mRegisteredReceivers.values().iterator();
13117                while (it.hasNext()) {
13118                    ReceiverList r = (ReceiverList)it.next();
13119                    if (dumpPackage != null && (r.app == null ||
13120                            !dumpPackage.equals(r.app.info.packageName))) {
13121                        continue;
13122                    }
13123                    if (!printed) {
13124                        pw.println("  Registered Receivers:");
13125                        needSep = true;
13126                        printed = true;
13127                        printedAnything = true;
13128                    }
13129                    pw.print("  * "); pw.println(r);
13130                    r.dump(pw, "    ");
13131                }
13132            }
13133
13134            if (mReceiverResolver.dump(pw, needSep ?
13135                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13136                    "    ", dumpPackage, false)) {
13137                needSep = true;
13138                printedAnything = true;
13139            }
13140        }
13141
13142        for (BroadcastQueue q : mBroadcastQueues) {
13143            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13144            printedAnything |= needSep;
13145        }
13146
13147        needSep = true;
13148
13149        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13150            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13151                if (needSep) {
13152                    pw.println();
13153                }
13154                needSep = true;
13155                printedAnything = true;
13156                pw.print("  Sticky broadcasts for user ");
13157                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13158                StringBuilder sb = new StringBuilder(128);
13159                for (Map.Entry<String, ArrayList<Intent>> ent
13160                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13161                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13162                    if (dumpAll) {
13163                        pw.println(":");
13164                        ArrayList<Intent> intents = ent.getValue();
13165                        final int N = intents.size();
13166                        for (int i=0; i<N; i++) {
13167                            sb.setLength(0);
13168                            sb.append("    Intent: ");
13169                            intents.get(i).toShortString(sb, false, true, false, false);
13170                            pw.println(sb.toString());
13171                            Bundle bundle = intents.get(i).getExtras();
13172                            if (bundle != null) {
13173                                pw.print("      ");
13174                                pw.println(bundle.toString());
13175                            }
13176                        }
13177                    } else {
13178                        pw.println("");
13179                    }
13180                }
13181            }
13182        }
13183
13184        if (!onlyHistory && dumpAll) {
13185            pw.println();
13186            for (BroadcastQueue queue : mBroadcastQueues) {
13187                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13188                        + queue.mBroadcastsScheduled);
13189            }
13190            pw.println("  mHandler:");
13191            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13192            needSep = true;
13193            printedAnything = true;
13194        }
13195
13196        if (!printedAnything) {
13197            pw.println("  (nothing)");
13198        }
13199    }
13200
13201    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13202            int opti, boolean dumpAll, String dumpPackage) {
13203        boolean needSep;
13204        boolean printedAnything = false;
13205
13206        ItemMatcher matcher = new ItemMatcher();
13207        matcher.build(args, opti);
13208
13209        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13210
13211        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13212        printedAnything |= needSep;
13213
13214        if (mLaunchingProviders.size() > 0) {
13215            boolean printed = false;
13216            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13217                ContentProviderRecord r = mLaunchingProviders.get(i);
13218                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13219                    continue;
13220                }
13221                if (!printed) {
13222                    if (needSep) pw.println();
13223                    needSep = true;
13224                    pw.println("  Launching content providers:");
13225                    printed = true;
13226                    printedAnything = true;
13227                }
13228                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13229                        pw.println(r);
13230            }
13231        }
13232
13233        if (mGrantedUriPermissions.size() > 0) {
13234            boolean printed = false;
13235            int dumpUid = -2;
13236            if (dumpPackage != null) {
13237                try {
13238                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13239                } catch (NameNotFoundException e) {
13240                    dumpUid = -1;
13241                }
13242            }
13243            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13244                int uid = mGrantedUriPermissions.keyAt(i);
13245                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13246                    continue;
13247                }
13248                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13249                if (!printed) {
13250                    if (needSep) pw.println();
13251                    needSep = true;
13252                    pw.println("  Granted Uri Permissions:");
13253                    printed = true;
13254                    printedAnything = true;
13255                }
13256                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13257                for (UriPermission perm : perms.values()) {
13258                    pw.print("    "); pw.println(perm);
13259                    if (dumpAll) {
13260                        perm.dump(pw, "      ");
13261                    }
13262                }
13263            }
13264        }
13265
13266        if (!printedAnything) {
13267            pw.println("  (nothing)");
13268        }
13269    }
13270
13271    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13272            int opti, boolean dumpAll, String dumpPackage) {
13273        boolean printed = false;
13274
13275        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13276
13277        if (mIntentSenderRecords.size() > 0) {
13278            Iterator<WeakReference<PendingIntentRecord>> it
13279                    = mIntentSenderRecords.values().iterator();
13280            while (it.hasNext()) {
13281                WeakReference<PendingIntentRecord> ref = it.next();
13282                PendingIntentRecord rec = ref != null ? ref.get(): null;
13283                if (dumpPackage != null && (rec == null
13284                        || !dumpPackage.equals(rec.key.packageName))) {
13285                    continue;
13286                }
13287                printed = true;
13288                if (rec != null) {
13289                    pw.print("  * "); pw.println(rec);
13290                    if (dumpAll) {
13291                        rec.dump(pw, "    ");
13292                    }
13293                } else {
13294                    pw.print("  * "); pw.println(ref);
13295                }
13296            }
13297        }
13298
13299        if (!printed) {
13300            pw.println("  (nothing)");
13301        }
13302    }
13303
13304    private static final int dumpProcessList(PrintWriter pw,
13305            ActivityManagerService service, List list,
13306            String prefix, String normalLabel, String persistentLabel,
13307            String dumpPackage) {
13308        int numPers = 0;
13309        final int N = list.size()-1;
13310        for (int i=N; i>=0; i--) {
13311            ProcessRecord r = (ProcessRecord)list.get(i);
13312            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13313                continue;
13314            }
13315            pw.println(String.format("%s%s #%2d: %s",
13316                    prefix, (r.persistent ? persistentLabel : normalLabel),
13317                    i, r.toString()));
13318            if (r.persistent) {
13319                numPers++;
13320            }
13321        }
13322        return numPers;
13323    }
13324
13325    private static final boolean dumpProcessOomList(PrintWriter pw,
13326            ActivityManagerService service, List<ProcessRecord> origList,
13327            String prefix, String normalLabel, String persistentLabel,
13328            boolean inclDetails, String dumpPackage) {
13329
13330        ArrayList<Pair<ProcessRecord, Integer>> list
13331                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13332        for (int i=0; i<origList.size(); i++) {
13333            ProcessRecord r = origList.get(i);
13334            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13335                continue;
13336            }
13337            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13338        }
13339
13340        if (list.size() <= 0) {
13341            return false;
13342        }
13343
13344        Comparator<Pair<ProcessRecord, Integer>> comparator
13345                = new Comparator<Pair<ProcessRecord, Integer>>() {
13346            @Override
13347            public int compare(Pair<ProcessRecord, Integer> object1,
13348                    Pair<ProcessRecord, Integer> object2) {
13349                if (object1.first.setAdj != object2.first.setAdj) {
13350                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13351                }
13352                if (object1.second.intValue() != object2.second.intValue()) {
13353                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13354                }
13355                return 0;
13356            }
13357        };
13358
13359        Collections.sort(list, comparator);
13360
13361        final long curRealtime = SystemClock.elapsedRealtime();
13362        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13363        final long curUptime = SystemClock.uptimeMillis();
13364        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13365
13366        for (int i=list.size()-1; i>=0; i--) {
13367            ProcessRecord r = list.get(i).first;
13368            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13369            char schedGroup;
13370            switch (r.setSchedGroup) {
13371                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13372                    schedGroup = 'B';
13373                    break;
13374                case Process.THREAD_GROUP_DEFAULT:
13375                    schedGroup = 'F';
13376                    break;
13377                default:
13378                    schedGroup = '?';
13379                    break;
13380            }
13381            char foreground;
13382            if (r.foregroundActivities) {
13383                foreground = 'A';
13384            } else if (r.foregroundServices) {
13385                foreground = 'S';
13386            } else {
13387                foreground = ' ';
13388            }
13389            String procState = ProcessList.makeProcStateString(r.curProcState);
13390            pw.print(prefix);
13391            pw.print(r.persistent ? persistentLabel : normalLabel);
13392            pw.print(" #");
13393            int num = (origList.size()-1)-list.get(i).second;
13394            if (num < 10) pw.print(' ');
13395            pw.print(num);
13396            pw.print(": ");
13397            pw.print(oomAdj);
13398            pw.print(' ');
13399            pw.print(schedGroup);
13400            pw.print('/');
13401            pw.print(foreground);
13402            pw.print('/');
13403            pw.print(procState);
13404            pw.print(" trm:");
13405            if (r.trimMemoryLevel < 10) pw.print(' ');
13406            pw.print(r.trimMemoryLevel);
13407            pw.print(' ');
13408            pw.print(r.toShortString());
13409            pw.print(" (");
13410            pw.print(r.adjType);
13411            pw.println(')');
13412            if (r.adjSource != null || r.adjTarget != null) {
13413                pw.print(prefix);
13414                pw.print("    ");
13415                if (r.adjTarget instanceof ComponentName) {
13416                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13417                } else if (r.adjTarget != null) {
13418                    pw.print(r.adjTarget.toString());
13419                } else {
13420                    pw.print("{null}");
13421                }
13422                pw.print("<=");
13423                if (r.adjSource instanceof ProcessRecord) {
13424                    pw.print("Proc{");
13425                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13426                    pw.println("}");
13427                } else if (r.adjSource != null) {
13428                    pw.println(r.adjSource.toString());
13429                } else {
13430                    pw.println("{null}");
13431                }
13432            }
13433            if (inclDetails) {
13434                pw.print(prefix);
13435                pw.print("    ");
13436                pw.print("oom: max="); pw.print(r.maxAdj);
13437                pw.print(" curRaw="); pw.print(r.curRawAdj);
13438                pw.print(" setRaw="); pw.print(r.setRawAdj);
13439                pw.print(" cur="); pw.print(r.curAdj);
13440                pw.print(" set="); pw.println(r.setAdj);
13441                pw.print(prefix);
13442                pw.print("    ");
13443                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13444                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13445                pw.print(" lastPss="); pw.print(r.lastPss);
13446                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13447                pw.print(prefix);
13448                pw.print("    ");
13449                pw.print("cached="); pw.print(r.cached);
13450                pw.print(" empty="); pw.print(r.empty);
13451                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13452
13453                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13454                    if (r.lastWakeTime != 0) {
13455                        long wtime;
13456                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13457                        synchronized (stats) {
13458                            wtime = stats.getProcessWakeTime(r.info.uid,
13459                                    r.pid, curRealtime);
13460                        }
13461                        long timeUsed = wtime - r.lastWakeTime;
13462                        pw.print(prefix);
13463                        pw.print("    ");
13464                        pw.print("keep awake over ");
13465                        TimeUtils.formatDuration(realtimeSince, pw);
13466                        pw.print(" used ");
13467                        TimeUtils.formatDuration(timeUsed, pw);
13468                        pw.print(" (");
13469                        pw.print((timeUsed*100)/realtimeSince);
13470                        pw.println("%)");
13471                    }
13472                    if (r.lastCpuTime != 0) {
13473                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13474                        pw.print(prefix);
13475                        pw.print("    ");
13476                        pw.print("run cpu over ");
13477                        TimeUtils.formatDuration(uptimeSince, pw);
13478                        pw.print(" used ");
13479                        TimeUtils.formatDuration(timeUsed, pw);
13480                        pw.print(" (");
13481                        pw.print((timeUsed*100)/uptimeSince);
13482                        pw.println("%)");
13483                    }
13484                }
13485            }
13486        }
13487        return true;
13488    }
13489
13490    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13491        ArrayList<ProcessRecord> procs;
13492        synchronized (this) {
13493            if (args != null && args.length > start
13494                    && args[start].charAt(0) != '-') {
13495                procs = new ArrayList<ProcessRecord>();
13496                int pid = -1;
13497                try {
13498                    pid = Integer.parseInt(args[start]);
13499                } catch (NumberFormatException e) {
13500                }
13501                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13502                    ProcessRecord proc = mLruProcesses.get(i);
13503                    if (proc.pid == pid) {
13504                        procs.add(proc);
13505                    } else if (proc.processName.equals(args[start])) {
13506                        procs.add(proc);
13507                    }
13508                }
13509                if (procs.size() <= 0) {
13510                    return null;
13511                }
13512            } else {
13513                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13514            }
13515        }
13516        return procs;
13517    }
13518
13519    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13520            PrintWriter pw, String[] args) {
13521        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13522        if (procs == null) {
13523            pw.println("No process found for: " + args[0]);
13524            return;
13525        }
13526
13527        long uptime = SystemClock.uptimeMillis();
13528        long realtime = SystemClock.elapsedRealtime();
13529        pw.println("Applications Graphics Acceleration Info:");
13530        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13531
13532        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13533            ProcessRecord r = procs.get(i);
13534            if (r.thread != null) {
13535                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13536                pw.flush();
13537                try {
13538                    TransferPipe tp = new TransferPipe();
13539                    try {
13540                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13541                        tp.go(fd);
13542                    } finally {
13543                        tp.kill();
13544                    }
13545                } catch (IOException e) {
13546                    pw.println("Failure while dumping the app: " + r);
13547                    pw.flush();
13548                } catch (RemoteException e) {
13549                    pw.println("Got a RemoteException while dumping the app " + r);
13550                    pw.flush();
13551                }
13552            }
13553        }
13554    }
13555
13556    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13557        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13558        if (procs == null) {
13559            pw.println("No process found for: " + args[0]);
13560            return;
13561        }
13562
13563        pw.println("Applications Database Info:");
13564
13565        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13566            ProcessRecord r = procs.get(i);
13567            if (r.thread != null) {
13568                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13569                pw.flush();
13570                try {
13571                    TransferPipe tp = new TransferPipe();
13572                    try {
13573                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13574                        tp.go(fd);
13575                    } finally {
13576                        tp.kill();
13577                    }
13578                } catch (IOException e) {
13579                    pw.println("Failure while dumping the app: " + r);
13580                    pw.flush();
13581                } catch (RemoteException e) {
13582                    pw.println("Got a RemoteException while dumping the app " + r);
13583                    pw.flush();
13584                }
13585            }
13586        }
13587    }
13588
13589    final static class MemItem {
13590        final boolean isProc;
13591        final String label;
13592        final String shortLabel;
13593        final long pss;
13594        final int id;
13595        final boolean hasActivities;
13596        ArrayList<MemItem> subitems;
13597
13598        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13599                boolean _hasActivities) {
13600            isProc = true;
13601            label = _label;
13602            shortLabel = _shortLabel;
13603            pss = _pss;
13604            id = _id;
13605            hasActivities = _hasActivities;
13606        }
13607
13608        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13609            isProc = false;
13610            label = _label;
13611            shortLabel = _shortLabel;
13612            pss = _pss;
13613            id = _id;
13614            hasActivities = false;
13615        }
13616    }
13617
13618    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13619            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13620        if (sort && !isCompact) {
13621            Collections.sort(items, new Comparator<MemItem>() {
13622                @Override
13623                public int compare(MemItem lhs, MemItem rhs) {
13624                    if (lhs.pss < rhs.pss) {
13625                        return 1;
13626                    } else if (lhs.pss > rhs.pss) {
13627                        return -1;
13628                    }
13629                    return 0;
13630                }
13631            });
13632        }
13633
13634        for (int i=0; i<items.size(); i++) {
13635            MemItem mi = items.get(i);
13636            if (!isCompact) {
13637                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13638            } else if (mi.isProc) {
13639                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13640                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13641                pw.println(mi.hasActivities ? ",a" : ",e");
13642            } else {
13643                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13644                pw.println(mi.pss);
13645            }
13646            if (mi.subitems != null) {
13647                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13648                        true, isCompact);
13649            }
13650        }
13651    }
13652
13653    // These are in KB.
13654    static final long[] DUMP_MEM_BUCKETS = new long[] {
13655        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13656        120*1024, 160*1024, 200*1024,
13657        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13658        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13659    };
13660
13661    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13662            boolean stackLike) {
13663        int start = label.lastIndexOf('.');
13664        if (start >= 0) start++;
13665        else start = 0;
13666        int end = label.length();
13667        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13668            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13669                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13670                out.append(bucket);
13671                out.append(stackLike ? "MB." : "MB ");
13672                out.append(label, start, end);
13673                return;
13674            }
13675        }
13676        out.append(memKB/1024);
13677        out.append(stackLike ? "MB." : "MB ");
13678        out.append(label, start, end);
13679    }
13680
13681    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13682            ProcessList.NATIVE_ADJ,
13683            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13684            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13685            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13686            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13687            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13688    };
13689    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13690            "Native",
13691            "System", "Persistent", "Foreground",
13692            "Visible", "Perceptible",
13693            "Heavy Weight", "Backup",
13694            "A Services", "Home",
13695            "Previous", "B Services", "Cached"
13696    };
13697    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13698            "native",
13699            "sys", "pers", "fore",
13700            "vis", "percept",
13701            "heavy", "backup",
13702            "servicea", "home",
13703            "prev", "serviceb", "cached"
13704    };
13705
13706    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13707            long realtime, boolean isCheckinRequest, boolean isCompact) {
13708        if (isCheckinRequest || isCompact) {
13709            // short checkin version
13710            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13711        } else {
13712            pw.println("Applications Memory Usage (kB):");
13713            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13714        }
13715    }
13716
13717    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13718            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13719        boolean dumpDetails = false;
13720        boolean dumpFullDetails = false;
13721        boolean dumpDalvik = false;
13722        boolean oomOnly = false;
13723        boolean isCompact = false;
13724        boolean localOnly = false;
13725
13726        int opti = 0;
13727        while (opti < args.length) {
13728            String opt = args[opti];
13729            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13730                break;
13731            }
13732            opti++;
13733            if ("-a".equals(opt)) {
13734                dumpDetails = true;
13735                dumpFullDetails = true;
13736                dumpDalvik = true;
13737            } else if ("-d".equals(opt)) {
13738                dumpDalvik = true;
13739            } else if ("-c".equals(opt)) {
13740                isCompact = true;
13741            } else if ("--oom".equals(opt)) {
13742                oomOnly = true;
13743            } else if ("--local".equals(opt)) {
13744                localOnly = true;
13745            } else if ("-h".equals(opt)) {
13746                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13747                pw.println("  -a: include all available information for each process.");
13748                pw.println("  -d: include dalvik details when dumping process details.");
13749                pw.println("  -c: dump in a compact machine-parseable representation.");
13750                pw.println("  --oom: only show processes organized by oom adj.");
13751                pw.println("  --local: only collect details locally, don't call process.");
13752                pw.println("If [process] is specified it can be the name or ");
13753                pw.println("pid of a specific process to dump.");
13754                return;
13755            } else {
13756                pw.println("Unknown argument: " + opt + "; use -h for help");
13757            }
13758        }
13759
13760        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13761        long uptime = SystemClock.uptimeMillis();
13762        long realtime = SystemClock.elapsedRealtime();
13763        final long[] tmpLong = new long[1];
13764
13765        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13766        if (procs == null) {
13767            // No Java processes.  Maybe they want to print a native process.
13768            if (args != null && args.length > opti
13769                    && args[opti].charAt(0) != '-') {
13770                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13771                        = new ArrayList<ProcessCpuTracker.Stats>();
13772                updateCpuStatsNow();
13773                int findPid = -1;
13774                try {
13775                    findPid = Integer.parseInt(args[opti]);
13776                } catch (NumberFormatException e) {
13777                }
13778                synchronized (mProcessCpuTracker) {
13779                    final int N = mProcessCpuTracker.countStats();
13780                    for (int i=0; i<N; i++) {
13781                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13782                        if (st.pid == findPid || (st.baseName != null
13783                                && st.baseName.equals(args[opti]))) {
13784                            nativeProcs.add(st);
13785                        }
13786                    }
13787                }
13788                if (nativeProcs.size() > 0) {
13789                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13790                            isCompact);
13791                    Debug.MemoryInfo mi = null;
13792                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13793                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13794                        final int pid = r.pid;
13795                        if (!isCheckinRequest && dumpDetails) {
13796                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13797                        }
13798                        if (mi == null) {
13799                            mi = new Debug.MemoryInfo();
13800                        }
13801                        if (dumpDetails || (!brief && !oomOnly)) {
13802                            Debug.getMemoryInfo(pid, mi);
13803                        } else {
13804                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13805                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13806                        }
13807                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13808                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13809                        if (isCheckinRequest) {
13810                            pw.println();
13811                        }
13812                    }
13813                    return;
13814                }
13815            }
13816            pw.println("No process found for: " + args[opti]);
13817            return;
13818        }
13819
13820        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13821            dumpDetails = true;
13822        }
13823
13824        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13825
13826        String[] innerArgs = new String[args.length-opti];
13827        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13828
13829        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13830        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13831        long nativePss=0, dalvikPss=0, otherPss=0;
13832        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13833
13834        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13835        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13836                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13837
13838        long totalPss = 0;
13839        long cachedPss = 0;
13840
13841        Debug.MemoryInfo mi = null;
13842        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13843            final ProcessRecord r = procs.get(i);
13844            final IApplicationThread thread;
13845            final int pid;
13846            final int oomAdj;
13847            final boolean hasActivities;
13848            synchronized (this) {
13849                thread = r.thread;
13850                pid = r.pid;
13851                oomAdj = r.getSetAdjWithServices();
13852                hasActivities = r.activities.size() > 0;
13853            }
13854            if (thread != null) {
13855                if (!isCheckinRequest && dumpDetails) {
13856                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13857                }
13858                if (mi == null) {
13859                    mi = new Debug.MemoryInfo();
13860                }
13861                if (dumpDetails || (!brief && !oomOnly)) {
13862                    Debug.getMemoryInfo(pid, mi);
13863                } else {
13864                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13865                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13866                }
13867                if (dumpDetails) {
13868                    if (localOnly) {
13869                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13870                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13871                        if (isCheckinRequest) {
13872                            pw.println();
13873                        }
13874                    } else {
13875                        try {
13876                            pw.flush();
13877                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13878                                    dumpDalvik, innerArgs);
13879                        } catch (RemoteException e) {
13880                            if (!isCheckinRequest) {
13881                                pw.println("Got RemoteException!");
13882                                pw.flush();
13883                            }
13884                        }
13885                    }
13886                }
13887
13888                final long myTotalPss = mi.getTotalPss();
13889                final long myTotalUss = mi.getTotalUss();
13890
13891                synchronized (this) {
13892                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13893                        // Record this for posterity if the process has been stable.
13894                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13895                    }
13896                }
13897
13898                if (!isCheckinRequest && mi != null) {
13899                    totalPss += myTotalPss;
13900                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13901                            (hasActivities ? " / activities)" : ")"),
13902                            r.processName, myTotalPss, pid, hasActivities);
13903                    procMems.add(pssItem);
13904                    procMemsMap.put(pid, pssItem);
13905
13906                    nativePss += mi.nativePss;
13907                    dalvikPss += mi.dalvikPss;
13908                    otherPss += mi.otherPss;
13909                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13910                        long mem = mi.getOtherPss(j);
13911                        miscPss[j] += mem;
13912                        otherPss -= mem;
13913                    }
13914
13915                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13916                        cachedPss += myTotalPss;
13917                    }
13918
13919                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13920                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13921                                || oomIndex == (oomPss.length-1)) {
13922                            oomPss[oomIndex] += myTotalPss;
13923                            if (oomProcs[oomIndex] == null) {
13924                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13925                            }
13926                            oomProcs[oomIndex].add(pssItem);
13927                            break;
13928                        }
13929                    }
13930                }
13931            }
13932        }
13933
13934        long nativeProcTotalPss = 0;
13935
13936        if (!isCheckinRequest && procs.size() > 1) {
13937            // If we are showing aggregations, also look for native processes to
13938            // include so that our aggregations are more accurate.
13939            updateCpuStatsNow();
13940            synchronized (mProcessCpuTracker) {
13941                final int N = mProcessCpuTracker.countStats();
13942                for (int i=0; i<N; i++) {
13943                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13944                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13945                        if (mi == null) {
13946                            mi = new Debug.MemoryInfo();
13947                        }
13948                        if (!brief && !oomOnly) {
13949                            Debug.getMemoryInfo(st.pid, mi);
13950                        } else {
13951                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13952                            mi.nativePrivateDirty = (int)tmpLong[0];
13953                        }
13954
13955                        final long myTotalPss = mi.getTotalPss();
13956                        totalPss += myTotalPss;
13957                        nativeProcTotalPss += myTotalPss;
13958
13959                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13960                                st.name, myTotalPss, st.pid, false);
13961                        procMems.add(pssItem);
13962
13963                        nativePss += mi.nativePss;
13964                        dalvikPss += mi.dalvikPss;
13965                        otherPss += mi.otherPss;
13966                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13967                            long mem = mi.getOtherPss(j);
13968                            miscPss[j] += mem;
13969                            otherPss -= mem;
13970                        }
13971                        oomPss[0] += myTotalPss;
13972                        if (oomProcs[0] == null) {
13973                            oomProcs[0] = new ArrayList<MemItem>();
13974                        }
13975                        oomProcs[0].add(pssItem);
13976                    }
13977                }
13978            }
13979
13980            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13981
13982            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13983            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13984            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13985            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13986                String label = Debug.MemoryInfo.getOtherLabel(j);
13987                catMems.add(new MemItem(label, label, miscPss[j], j));
13988            }
13989
13990            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13991            for (int j=0; j<oomPss.length; j++) {
13992                if (oomPss[j] != 0) {
13993                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13994                            : DUMP_MEM_OOM_LABEL[j];
13995                    MemItem item = new MemItem(label, label, oomPss[j],
13996                            DUMP_MEM_OOM_ADJ[j]);
13997                    item.subitems = oomProcs[j];
13998                    oomMems.add(item);
13999                }
14000            }
14001
14002            if (!brief && !oomOnly && !isCompact) {
14003                pw.println();
14004                pw.println("Total PSS by process:");
14005                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14006                pw.println();
14007            }
14008            if (!isCompact) {
14009                pw.println("Total PSS by OOM adjustment:");
14010            }
14011            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14012            if (!brief && !oomOnly) {
14013                PrintWriter out = categoryPw != null ? categoryPw : pw;
14014                if (!isCompact) {
14015                    out.println();
14016                    out.println("Total PSS by category:");
14017                }
14018                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14019            }
14020            if (!isCompact) {
14021                pw.println();
14022            }
14023            MemInfoReader memInfo = new MemInfoReader();
14024            memInfo.readMemInfo();
14025            if (nativeProcTotalPss > 0) {
14026                synchronized (this) {
14027                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14028                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14029                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14030                            nativeProcTotalPss);
14031                }
14032            }
14033            if (!brief) {
14034                if (!isCompact) {
14035                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14036                    pw.print(" kB (status ");
14037                    switch (mLastMemoryLevel) {
14038                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14039                            pw.println("normal)");
14040                            break;
14041                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14042                            pw.println("moderate)");
14043                            break;
14044                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14045                            pw.println("low)");
14046                            break;
14047                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14048                            pw.println("critical)");
14049                            break;
14050                        default:
14051                            pw.print(mLastMemoryLevel);
14052                            pw.println(")");
14053                            break;
14054                    }
14055                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14056                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14057                            pw.print(cachedPss); pw.print(" cached pss + ");
14058                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14059                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14060                } else {
14061                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14062                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14063                            + memInfo.getFreeSizeKb()); pw.print(",");
14064                    pw.println(totalPss - cachedPss);
14065                }
14066            }
14067            if (!isCompact) {
14068                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14069                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14070                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14071                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14072                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14073                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14074                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14075                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14076                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14077                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14078                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14079            }
14080            if (!brief) {
14081                if (memInfo.getZramTotalSizeKb() != 0) {
14082                    if (!isCompact) {
14083                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14084                                pw.print(" kB physical used for ");
14085                                pw.print(memInfo.getSwapTotalSizeKb()
14086                                        - memInfo.getSwapFreeSizeKb());
14087                                pw.print(" kB in swap (");
14088                                pw.print(memInfo.getSwapTotalSizeKb());
14089                                pw.println(" kB total swap)");
14090                    } else {
14091                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14092                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14093                                pw.println(memInfo.getSwapFreeSizeKb());
14094                    }
14095                }
14096                final int[] SINGLE_LONG_FORMAT = new int[] {
14097                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14098                };
14099                long[] longOut = new long[1];
14100                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14101                        SINGLE_LONG_FORMAT, null, longOut, null);
14102                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14103                longOut[0] = 0;
14104                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14105                        SINGLE_LONG_FORMAT, null, longOut, null);
14106                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14107                longOut[0] = 0;
14108                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14109                        SINGLE_LONG_FORMAT, null, longOut, null);
14110                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14111                longOut[0] = 0;
14112                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14113                        SINGLE_LONG_FORMAT, null, longOut, null);
14114                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14115                if (!isCompact) {
14116                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14117                        pw.print("      KSM: "); pw.print(sharing);
14118                                pw.print(" kB saved from shared ");
14119                                pw.print(shared); pw.println(" kB");
14120                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14121                                pw.print(voltile); pw.println(" kB volatile");
14122                    }
14123                    pw.print("   Tuning: ");
14124                    pw.print(ActivityManager.staticGetMemoryClass());
14125                    pw.print(" (large ");
14126                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14127                    pw.print("), oom ");
14128                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14129                    pw.print(" kB");
14130                    pw.print(", restore limit ");
14131                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14132                    pw.print(" kB");
14133                    if (ActivityManager.isLowRamDeviceStatic()) {
14134                        pw.print(" (low-ram)");
14135                    }
14136                    if (ActivityManager.isHighEndGfx()) {
14137                        pw.print(" (high-end-gfx)");
14138                    }
14139                    pw.println();
14140                } else {
14141                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14142                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14143                    pw.println(voltile);
14144                    pw.print("tuning,");
14145                    pw.print(ActivityManager.staticGetMemoryClass());
14146                    pw.print(',');
14147                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14148                    pw.print(',');
14149                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14150                    if (ActivityManager.isLowRamDeviceStatic()) {
14151                        pw.print(",low-ram");
14152                    }
14153                    if (ActivityManager.isHighEndGfx()) {
14154                        pw.print(",high-end-gfx");
14155                    }
14156                    pw.println();
14157                }
14158            }
14159        }
14160    }
14161
14162    /**
14163     * Searches array of arguments for the specified string
14164     * @param args array of argument strings
14165     * @param value value to search for
14166     * @return true if the value is contained in the array
14167     */
14168    private static boolean scanArgs(String[] args, String value) {
14169        if (args != null) {
14170            for (String arg : args) {
14171                if (value.equals(arg)) {
14172                    return true;
14173                }
14174            }
14175        }
14176        return false;
14177    }
14178
14179    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14180            ContentProviderRecord cpr, boolean always) {
14181        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14182
14183        if (!inLaunching || always) {
14184            synchronized (cpr) {
14185                cpr.launchingApp = null;
14186                cpr.notifyAll();
14187            }
14188            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14189            String names[] = cpr.info.authority.split(";");
14190            for (int j = 0; j < names.length; j++) {
14191                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14192            }
14193        }
14194
14195        for (int i=0; i<cpr.connections.size(); i++) {
14196            ContentProviderConnection conn = cpr.connections.get(i);
14197            if (conn.waiting) {
14198                // If this connection is waiting for the provider, then we don't
14199                // need to mess with its process unless we are always removing
14200                // or for some reason the provider is not currently launching.
14201                if (inLaunching && !always) {
14202                    continue;
14203                }
14204            }
14205            ProcessRecord capp = conn.client;
14206            conn.dead = true;
14207            if (conn.stableCount > 0) {
14208                if (!capp.persistent && capp.thread != null
14209                        && capp.pid != 0
14210                        && capp.pid != MY_PID) {
14211                    capp.kill("depends on provider "
14212                            + cpr.name.flattenToShortString()
14213                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14214                }
14215            } else if (capp.thread != null && conn.provider.provider != null) {
14216                try {
14217                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14218                } catch (RemoteException e) {
14219                }
14220                // In the protocol here, we don't expect the client to correctly
14221                // clean up this connection, we'll just remove it.
14222                cpr.connections.remove(i);
14223                conn.client.conProviders.remove(conn);
14224            }
14225        }
14226
14227        if (inLaunching && always) {
14228            mLaunchingProviders.remove(cpr);
14229        }
14230        return inLaunching;
14231    }
14232
14233    /**
14234     * Main code for cleaning up a process when it has gone away.  This is
14235     * called both as a result of the process dying, or directly when stopping
14236     * a process when running in single process mode.
14237     */
14238    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14239            boolean restarting, boolean allowRestart, int index) {
14240        if (index >= 0) {
14241            removeLruProcessLocked(app);
14242            ProcessList.remove(app.pid);
14243        }
14244
14245        mProcessesToGc.remove(app);
14246        mPendingPssProcesses.remove(app);
14247
14248        // Dismiss any open dialogs.
14249        if (app.crashDialog != null && !app.forceCrashReport) {
14250            app.crashDialog.dismiss();
14251            app.crashDialog = null;
14252        }
14253        if (app.anrDialog != null) {
14254            app.anrDialog.dismiss();
14255            app.anrDialog = null;
14256        }
14257        if (app.waitDialog != null) {
14258            app.waitDialog.dismiss();
14259            app.waitDialog = null;
14260        }
14261
14262        app.crashing = false;
14263        app.notResponding = false;
14264
14265        app.resetPackageList(mProcessStats);
14266        app.unlinkDeathRecipient();
14267        app.makeInactive(mProcessStats);
14268        app.waitingToKill = null;
14269        app.forcingToForeground = null;
14270        updateProcessForegroundLocked(app, false, false);
14271        app.foregroundActivities = false;
14272        app.hasShownUi = false;
14273        app.treatLikeActivity = false;
14274        app.hasAboveClient = false;
14275        app.hasClientActivities = false;
14276
14277        mServices.killServicesLocked(app, allowRestart);
14278
14279        boolean restart = false;
14280
14281        // Remove published content providers.
14282        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14283            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14284            final boolean always = app.bad || !allowRestart;
14285            if (removeDyingProviderLocked(app, cpr, always) || always) {
14286                // We left the provider in the launching list, need to
14287                // restart it.
14288                restart = true;
14289            }
14290
14291            cpr.provider = null;
14292            cpr.proc = null;
14293        }
14294        app.pubProviders.clear();
14295
14296        // Take care of any launching providers waiting for this process.
14297        if (checkAppInLaunchingProvidersLocked(app, false)) {
14298            restart = true;
14299        }
14300
14301        // Unregister from connected content providers.
14302        if (!app.conProviders.isEmpty()) {
14303            for (int i=0; i<app.conProviders.size(); i++) {
14304                ContentProviderConnection conn = app.conProviders.get(i);
14305                conn.provider.connections.remove(conn);
14306            }
14307            app.conProviders.clear();
14308        }
14309
14310        // At this point there may be remaining entries in mLaunchingProviders
14311        // where we were the only one waiting, so they are no longer of use.
14312        // Look for these and clean up if found.
14313        // XXX Commented out for now.  Trying to figure out a way to reproduce
14314        // the actual situation to identify what is actually going on.
14315        if (false) {
14316            for (int i=0; i<mLaunchingProviders.size(); i++) {
14317                ContentProviderRecord cpr = (ContentProviderRecord)
14318                        mLaunchingProviders.get(i);
14319                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14320                    synchronized (cpr) {
14321                        cpr.launchingApp = null;
14322                        cpr.notifyAll();
14323                    }
14324                }
14325            }
14326        }
14327
14328        skipCurrentReceiverLocked(app);
14329
14330        // Unregister any receivers.
14331        for (int i=app.receivers.size()-1; i>=0; i--) {
14332            removeReceiverLocked(app.receivers.valueAt(i));
14333        }
14334        app.receivers.clear();
14335
14336        // If the app is undergoing backup, tell the backup manager about it
14337        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14338            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14339                    + mBackupTarget.appInfo + " died during backup");
14340            try {
14341                IBackupManager bm = IBackupManager.Stub.asInterface(
14342                        ServiceManager.getService(Context.BACKUP_SERVICE));
14343                bm.agentDisconnected(app.info.packageName);
14344            } catch (RemoteException e) {
14345                // can't happen; backup manager is local
14346            }
14347        }
14348
14349        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14350            ProcessChangeItem item = mPendingProcessChanges.get(i);
14351            if (item.pid == app.pid) {
14352                mPendingProcessChanges.remove(i);
14353                mAvailProcessChanges.add(item);
14354            }
14355        }
14356        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14357
14358        // If the caller is restarting this app, then leave it in its
14359        // current lists and let the caller take care of it.
14360        if (restarting) {
14361            return;
14362        }
14363
14364        if (!app.persistent || app.isolated) {
14365            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14366                    "Removing non-persistent process during cleanup: " + app);
14367            mProcessNames.remove(app.processName, app.uid);
14368            mIsolatedProcesses.remove(app.uid);
14369            if (mHeavyWeightProcess == app) {
14370                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14371                        mHeavyWeightProcess.userId, 0));
14372                mHeavyWeightProcess = null;
14373            }
14374        } else if (!app.removed) {
14375            // This app is persistent, so we need to keep its record around.
14376            // If it is not already on the pending app list, add it there
14377            // and start a new process for it.
14378            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14379                mPersistentStartingProcesses.add(app);
14380                restart = true;
14381            }
14382        }
14383        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14384                "Clean-up removing on hold: " + app);
14385        mProcessesOnHold.remove(app);
14386
14387        if (app == mHomeProcess) {
14388            mHomeProcess = null;
14389        }
14390        if (app == mPreviousProcess) {
14391            mPreviousProcess = null;
14392        }
14393
14394        if (restart && !app.isolated) {
14395            // We have components that still need to be running in the
14396            // process, so re-launch it.
14397            mProcessNames.put(app.processName, app.uid, app);
14398            startProcessLocked(app, "restart", app.processName);
14399        } else if (app.pid > 0 && app.pid != MY_PID) {
14400            // Goodbye!
14401            boolean removed;
14402            synchronized (mPidsSelfLocked) {
14403                mPidsSelfLocked.remove(app.pid);
14404                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14405            }
14406            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14407            if (app.isolated) {
14408                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14409            }
14410            app.setPid(0);
14411        }
14412    }
14413
14414    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14415        // Look through the content providers we are waiting to have launched,
14416        // and if any run in this process then either schedule a restart of
14417        // the process or kill the client waiting for it if this process has
14418        // gone bad.
14419        int NL = mLaunchingProviders.size();
14420        boolean restart = false;
14421        for (int i=0; i<NL; i++) {
14422            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14423            if (cpr.launchingApp == app) {
14424                if (!alwaysBad && !app.bad) {
14425                    restart = true;
14426                } else {
14427                    removeDyingProviderLocked(app, cpr, true);
14428                    // cpr should have been removed from mLaunchingProviders
14429                    NL = mLaunchingProviders.size();
14430                    i--;
14431                }
14432            }
14433        }
14434        return restart;
14435    }
14436
14437    // =========================================================
14438    // SERVICES
14439    // =========================================================
14440
14441    @Override
14442    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14443            int flags) {
14444        enforceNotIsolatedCaller("getServices");
14445        synchronized (this) {
14446            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14447        }
14448    }
14449
14450    @Override
14451    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14452        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14453        synchronized (this) {
14454            return mServices.getRunningServiceControlPanelLocked(name);
14455        }
14456    }
14457
14458    @Override
14459    public ComponentName startService(IApplicationThread caller, Intent service,
14460            String resolvedType, int userId) {
14461        enforceNotIsolatedCaller("startService");
14462        // Refuse possible leaked file descriptors
14463        if (service != null && service.hasFileDescriptors() == true) {
14464            throw new IllegalArgumentException("File descriptors passed in Intent");
14465        }
14466
14467        if (DEBUG_SERVICE)
14468            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14469        synchronized(this) {
14470            final int callingPid = Binder.getCallingPid();
14471            final int callingUid = Binder.getCallingUid();
14472            final long origId = Binder.clearCallingIdentity();
14473            ComponentName res = mServices.startServiceLocked(caller, service,
14474                    resolvedType, callingPid, callingUid, userId);
14475            Binder.restoreCallingIdentity(origId);
14476            return res;
14477        }
14478    }
14479
14480    ComponentName startServiceInPackage(int uid,
14481            Intent service, String resolvedType, int userId) {
14482        synchronized(this) {
14483            if (DEBUG_SERVICE)
14484                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14485            final long origId = Binder.clearCallingIdentity();
14486            ComponentName res = mServices.startServiceLocked(null, service,
14487                    resolvedType, -1, uid, userId);
14488            Binder.restoreCallingIdentity(origId);
14489            return res;
14490        }
14491    }
14492
14493    @Override
14494    public int stopService(IApplicationThread caller, Intent service,
14495            String resolvedType, int userId) {
14496        enforceNotIsolatedCaller("stopService");
14497        // Refuse possible leaked file descriptors
14498        if (service != null && service.hasFileDescriptors() == true) {
14499            throw new IllegalArgumentException("File descriptors passed in Intent");
14500        }
14501
14502        synchronized(this) {
14503            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14504        }
14505    }
14506
14507    @Override
14508    public IBinder peekService(Intent service, String resolvedType) {
14509        enforceNotIsolatedCaller("peekService");
14510        // Refuse possible leaked file descriptors
14511        if (service != null && service.hasFileDescriptors() == true) {
14512            throw new IllegalArgumentException("File descriptors passed in Intent");
14513        }
14514        synchronized(this) {
14515            return mServices.peekServiceLocked(service, resolvedType);
14516        }
14517    }
14518
14519    @Override
14520    public boolean stopServiceToken(ComponentName className, IBinder token,
14521            int startId) {
14522        synchronized(this) {
14523            return mServices.stopServiceTokenLocked(className, token, startId);
14524        }
14525    }
14526
14527    @Override
14528    public void setServiceForeground(ComponentName className, IBinder token,
14529            int id, Notification notification, boolean removeNotification) {
14530        synchronized(this) {
14531            mServices.setServiceForegroundLocked(className, token, id, notification,
14532                    removeNotification);
14533        }
14534    }
14535
14536    @Override
14537    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14538            boolean requireFull, String name, String callerPackage) {
14539        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14540                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14541    }
14542
14543    int unsafeConvertIncomingUser(int userId) {
14544        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14545                ? mCurrentUserId : userId;
14546    }
14547
14548    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14549            int allowMode, String name, String callerPackage) {
14550        final int callingUserId = UserHandle.getUserId(callingUid);
14551        if (callingUserId == userId) {
14552            return userId;
14553        }
14554
14555        // Note that we may be accessing mCurrentUserId outside of a lock...
14556        // shouldn't be a big deal, if this is being called outside
14557        // of a locked context there is intrinsically a race with
14558        // the value the caller will receive and someone else changing it.
14559        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14560        // we will switch to the calling user if access to the current user fails.
14561        int targetUserId = unsafeConvertIncomingUser(userId);
14562
14563        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14564            final boolean allow;
14565            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14566                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14567                // If the caller has this permission, they always pass go.  And collect $200.
14568                allow = true;
14569            } else if (allowMode == ALLOW_FULL_ONLY) {
14570                // We require full access, sucks to be you.
14571                allow = false;
14572            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14573                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14574                // If the caller does not have either permission, they are always doomed.
14575                allow = false;
14576            } else if (allowMode == ALLOW_NON_FULL) {
14577                // We are blanket allowing non-full access, you lucky caller!
14578                allow = true;
14579            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14580                // We may or may not allow this depending on whether the two users are
14581                // in the same profile.
14582                synchronized (mUserProfileGroupIdsSelfLocked) {
14583                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14584                            UserInfo.NO_PROFILE_GROUP_ID);
14585                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14586                            UserInfo.NO_PROFILE_GROUP_ID);
14587                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14588                            && callingProfile == targetProfile;
14589                }
14590            } else {
14591                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14592            }
14593            if (!allow) {
14594                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14595                    // In this case, they would like to just execute as their
14596                    // owner user instead of failing.
14597                    targetUserId = callingUserId;
14598                } else {
14599                    StringBuilder builder = new StringBuilder(128);
14600                    builder.append("Permission Denial: ");
14601                    builder.append(name);
14602                    if (callerPackage != null) {
14603                        builder.append(" from ");
14604                        builder.append(callerPackage);
14605                    }
14606                    builder.append(" asks to run as user ");
14607                    builder.append(userId);
14608                    builder.append(" but is calling from user ");
14609                    builder.append(UserHandle.getUserId(callingUid));
14610                    builder.append("; this requires ");
14611                    builder.append(INTERACT_ACROSS_USERS_FULL);
14612                    if (allowMode != ALLOW_FULL_ONLY) {
14613                        builder.append(" or ");
14614                        builder.append(INTERACT_ACROSS_USERS);
14615                    }
14616                    String msg = builder.toString();
14617                    Slog.w(TAG, msg);
14618                    throw new SecurityException(msg);
14619                }
14620            }
14621        }
14622        if (!allowAll && targetUserId < 0) {
14623            throw new IllegalArgumentException(
14624                    "Call does not support special user #" + targetUserId);
14625        }
14626        // Check shell permission
14627        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14628            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14629                    targetUserId)) {
14630                throw new SecurityException("Shell does not have permission to access user "
14631                        + targetUserId + "\n " + Debug.getCallers(3));
14632            }
14633        }
14634        return targetUserId;
14635    }
14636
14637    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14638            String className, int flags) {
14639        boolean result = false;
14640        // For apps that don't have pre-defined UIDs, check for permission
14641        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14642            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14643                if (ActivityManager.checkUidPermission(
14644                        INTERACT_ACROSS_USERS,
14645                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14646                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14647                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14648                            + " requests FLAG_SINGLE_USER, but app does not hold "
14649                            + INTERACT_ACROSS_USERS;
14650                    Slog.w(TAG, msg);
14651                    throw new SecurityException(msg);
14652                }
14653                // Permission passed
14654                result = true;
14655            }
14656        } else if ("system".equals(componentProcessName)) {
14657            result = true;
14658        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14659            // Phone app and persistent apps are allowed to export singleuser providers.
14660            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14661                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14662        }
14663        if (DEBUG_MU) {
14664            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14665                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14666        }
14667        return result;
14668    }
14669
14670    /**
14671     * Checks to see if the caller is in the same app as the singleton
14672     * component, or the component is in a special app. It allows special apps
14673     * to export singleton components but prevents exporting singleton
14674     * components for regular apps.
14675     */
14676    boolean isValidSingletonCall(int callingUid, int componentUid) {
14677        int componentAppId = UserHandle.getAppId(componentUid);
14678        return UserHandle.isSameApp(callingUid, componentUid)
14679                || componentAppId == Process.SYSTEM_UID
14680                || componentAppId == Process.PHONE_UID
14681                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14682                        == PackageManager.PERMISSION_GRANTED;
14683    }
14684
14685    public int bindService(IApplicationThread caller, IBinder token,
14686            Intent service, String resolvedType,
14687            IServiceConnection connection, int flags, int userId) {
14688        enforceNotIsolatedCaller("bindService");
14689
14690        // Refuse possible leaked file descriptors
14691        if (service != null && service.hasFileDescriptors() == true) {
14692            throw new IllegalArgumentException("File descriptors passed in Intent");
14693        }
14694
14695        synchronized(this) {
14696            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14697                    connection, flags, userId);
14698        }
14699    }
14700
14701    public boolean unbindService(IServiceConnection connection) {
14702        synchronized (this) {
14703            return mServices.unbindServiceLocked(connection);
14704        }
14705    }
14706
14707    public void publishService(IBinder token, Intent intent, IBinder service) {
14708        // Refuse possible leaked file descriptors
14709        if (intent != null && intent.hasFileDescriptors() == true) {
14710            throw new IllegalArgumentException("File descriptors passed in Intent");
14711        }
14712
14713        synchronized(this) {
14714            if (!(token instanceof ServiceRecord)) {
14715                throw new IllegalArgumentException("Invalid service token");
14716            }
14717            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14718        }
14719    }
14720
14721    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14722        // Refuse possible leaked file descriptors
14723        if (intent != null && intent.hasFileDescriptors() == true) {
14724            throw new IllegalArgumentException("File descriptors passed in Intent");
14725        }
14726
14727        synchronized(this) {
14728            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14729        }
14730    }
14731
14732    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14733        synchronized(this) {
14734            if (!(token instanceof ServiceRecord)) {
14735                throw new IllegalArgumentException("Invalid service token");
14736            }
14737            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14738        }
14739    }
14740
14741    // =========================================================
14742    // BACKUP AND RESTORE
14743    // =========================================================
14744
14745    // Cause the target app to be launched if necessary and its backup agent
14746    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14747    // activity manager to announce its creation.
14748    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14749        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14750        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14751
14752        synchronized(this) {
14753            // !!! TODO: currently no check here that we're already bound
14754            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14755            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14756            synchronized (stats) {
14757                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14758            }
14759
14760            // Backup agent is now in use, its package can't be stopped.
14761            try {
14762                AppGlobals.getPackageManager().setPackageStoppedState(
14763                        app.packageName, false, UserHandle.getUserId(app.uid));
14764            } catch (RemoteException e) {
14765            } catch (IllegalArgumentException e) {
14766                Slog.w(TAG, "Failed trying to unstop package "
14767                        + app.packageName + ": " + e);
14768            }
14769
14770            BackupRecord r = new BackupRecord(ss, app, backupMode);
14771            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14772                    ? new ComponentName(app.packageName, app.backupAgentName)
14773                    : new ComponentName("android", "FullBackupAgent");
14774            // startProcessLocked() returns existing proc's record if it's already running
14775            ProcessRecord proc = startProcessLocked(app.processName, app,
14776                    false, 0, "backup", hostingName, false, false, false);
14777            if (proc == null) {
14778                Slog.e(TAG, "Unable to start backup agent process " + r);
14779                return false;
14780            }
14781
14782            r.app = proc;
14783            mBackupTarget = r;
14784            mBackupAppName = app.packageName;
14785
14786            // Try not to kill the process during backup
14787            updateOomAdjLocked(proc);
14788
14789            // If the process is already attached, schedule the creation of the backup agent now.
14790            // If it is not yet live, this will be done when it attaches to the framework.
14791            if (proc.thread != null) {
14792                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14793                try {
14794                    proc.thread.scheduleCreateBackupAgent(app,
14795                            compatibilityInfoForPackageLocked(app), backupMode);
14796                } catch (RemoteException e) {
14797                    // Will time out on the backup manager side
14798                }
14799            } else {
14800                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14801            }
14802            // Invariants: at this point, the target app process exists and the application
14803            // is either already running or in the process of coming up.  mBackupTarget and
14804            // mBackupAppName describe the app, so that when it binds back to the AM we
14805            // know that it's scheduled for a backup-agent operation.
14806        }
14807
14808        return true;
14809    }
14810
14811    @Override
14812    public void clearPendingBackup() {
14813        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14814        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14815
14816        synchronized (this) {
14817            mBackupTarget = null;
14818            mBackupAppName = null;
14819        }
14820    }
14821
14822    // A backup agent has just come up
14823    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14824        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14825                + " = " + agent);
14826
14827        synchronized(this) {
14828            if (!agentPackageName.equals(mBackupAppName)) {
14829                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14830                return;
14831            }
14832        }
14833
14834        long oldIdent = Binder.clearCallingIdentity();
14835        try {
14836            IBackupManager bm = IBackupManager.Stub.asInterface(
14837                    ServiceManager.getService(Context.BACKUP_SERVICE));
14838            bm.agentConnected(agentPackageName, agent);
14839        } catch (RemoteException e) {
14840            // can't happen; the backup manager service is local
14841        } catch (Exception e) {
14842            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14843            e.printStackTrace();
14844        } finally {
14845            Binder.restoreCallingIdentity(oldIdent);
14846        }
14847    }
14848
14849    // done with this agent
14850    public void unbindBackupAgent(ApplicationInfo appInfo) {
14851        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14852        if (appInfo == null) {
14853            Slog.w(TAG, "unbind backup agent for null app");
14854            return;
14855        }
14856
14857        synchronized(this) {
14858            try {
14859                if (mBackupAppName == null) {
14860                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14861                    return;
14862                }
14863
14864                if (!mBackupAppName.equals(appInfo.packageName)) {
14865                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14866                    return;
14867                }
14868
14869                // Not backing this app up any more; reset its OOM adjustment
14870                final ProcessRecord proc = mBackupTarget.app;
14871                updateOomAdjLocked(proc);
14872
14873                // If the app crashed during backup, 'thread' will be null here
14874                if (proc.thread != null) {
14875                    try {
14876                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14877                                compatibilityInfoForPackageLocked(appInfo));
14878                    } catch (Exception e) {
14879                        Slog.e(TAG, "Exception when unbinding backup agent:");
14880                        e.printStackTrace();
14881                    }
14882                }
14883            } finally {
14884                mBackupTarget = null;
14885                mBackupAppName = null;
14886            }
14887        }
14888    }
14889    // =========================================================
14890    // BROADCASTS
14891    // =========================================================
14892
14893    private final List getStickiesLocked(String action, IntentFilter filter,
14894            List cur, int userId) {
14895        final ContentResolver resolver = mContext.getContentResolver();
14896        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14897        if (stickies == null) {
14898            return cur;
14899        }
14900        final ArrayList<Intent> list = stickies.get(action);
14901        if (list == null) {
14902            return cur;
14903        }
14904        int N = list.size();
14905        for (int i=0; i<N; i++) {
14906            Intent intent = list.get(i);
14907            if (filter.match(resolver, intent, true, TAG) >= 0) {
14908                if (cur == null) {
14909                    cur = new ArrayList<Intent>();
14910                }
14911                cur.add(intent);
14912            }
14913        }
14914        return cur;
14915    }
14916
14917    boolean isPendingBroadcastProcessLocked(int pid) {
14918        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14919                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14920    }
14921
14922    void skipPendingBroadcastLocked(int pid) {
14923            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14924            for (BroadcastQueue queue : mBroadcastQueues) {
14925                queue.skipPendingBroadcastLocked(pid);
14926            }
14927    }
14928
14929    // The app just attached; send any pending broadcasts that it should receive
14930    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14931        boolean didSomething = false;
14932        for (BroadcastQueue queue : mBroadcastQueues) {
14933            didSomething |= queue.sendPendingBroadcastsLocked(app);
14934        }
14935        return didSomething;
14936    }
14937
14938    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14939            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14940        enforceNotIsolatedCaller("registerReceiver");
14941        int callingUid;
14942        int callingPid;
14943        synchronized(this) {
14944            ProcessRecord callerApp = null;
14945            if (caller != null) {
14946                callerApp = getRecordForAppLocked(caller);
14947                if (callerApp == null) {
14948                    throw new SecurityException(
14949                            "Unable to find app for caller " + caller
14950                            + " (pid=" + Binder.getCallingPid()
14951                            + ") when registering receiver " + receiver);
14952                }
14953                if (callerApp.info.uid != Process.SYSTEM_UID &&
14954                        !callerApp.pkgList.containsKey(callerPackage) &&
14955                        !"android".equals(callerPackage)) {
14956                    throw new SecurityException("Given caller package " + callerPackage
14957                            + " is not running in process " + callerApp);
14958                }
14959                callingUid = callerApp.info.uid;
14960                callingPid = callerApp.pid;
14961            } else {
14962                callerPackage = null;
14963                callingUid = Binder.getCallingUid();
14964                callingPid = Binder.getCallingPid();
14965            }
14966
14967            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14968                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14969
14970            List allSticky = null;
14971
14972            // Look for any matching sticky broadcasts...
14973            Iterator actions = filter.actionsIterator();
14974            if (actions != null) {
14975                while (actions.hasNext()) {
14976                    String action = (String)actions.next();
14977                    allSticky = getStickiesLocked(action, filter, allSticky,
14978                            UserHandle.USER_ALL);
14979                    allSticky = getStickiesLocked(action, filter, allSticky,
14980                            UserHandle.getUserId(callingUid));
14981                }
14982            } else {
14983                allSticky = getStickiesLocked(null, filter, allSticky,
14984                        UserHandle.USER_ALL);
14985                allSticky = getStickiesLocked(null, filter, allSticky,
14986                        UserHandle.getUserId(callingUid));
14987            }
14988
14989            // The first sticky in the list is returned directly back to
14990            // the client.
14991            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14992
14993            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14994                    + ": " + sticky);
14995
14996            if (receiver == null) {
14997                return sticky;
14998            }
14999
15000            ReceiverList rl
15001                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15002            if (rl == null) {
15003                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15004                        userId, receiver);
15005                if (rl.app != null) {
15006                    rl.app.receivers.add(rl);
15007                } else {
15008                    try {
15009                        receiver.asBinder().linkToDeath(rl, 0);
15010                    } catch (RemoteException e) {
15011                        return sticky;
15012                    }
15013                    rl.linkedToDeath = true;
15014                }
15015                mRegisteredReceivers.put(receiver.asBinder(), rl);
15016            } else if (rl.uid != callingUid) {
15017                throw new IllegalArgumentException(
15018                        "Receiver requested to register for uid " + callingUid
15019                        + " was previously registered for uid " + rl.uid);
15020            } else if (rl.pid != callingPid) {
15021                throw new IllegalArgumentException(
15022                        "Receiver requested to register for pid " + callingPid
15023                        + " was previously registered for pid " + rl.pid);
15024            } else if (rl.userId != userId) {
15025                throw new IllegalArgumentException(
15026                        "Receiver requested to register for user " + userId
15027                        + " was previously registered for user " + rl.userId);
15028            }
15029            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15030                    permission, callingUid, userId);
15031            rl.add(bf);
15032            if (!bf.debugCheck()) {
15033                Slog.w(TAG, "==> For Dynamic broadast");
15034            }
15035            mReceiverResolver.addFilter(bf);
15036
15037            // Enqueue broadcasts for all existing stickies that match
15038            // this filter.
15039            if (allSticky != null) {
15040                ArrayList receivers = new ArrayList();
15041                receivers.add(bf);
15042
15043                int N = allSticky.size();
15044                for (int i=0; i<N; i++) {
15045                    Intent intent = (Intent)allSticky.get(i);
15046                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15047                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15048                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15049                            null, null, false, true, true, -1);
15050                    queue.enqueueParallelBroadcastLocked(r);
15051                    queue.scheduleBroadcastsLocked();
15052                }
15053            }
15054
15055            return sticky;
15056        }
15057    }
15058
15059    public void unregisterReceiver(IIntentReceiver receiver) {
15060        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15061
15062        final long origId = Binder.clearCallingIdentity();
15063        try {
15064            boolean doTrim = false;
15065
15066            synchronized(this) {
15067                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15068                if (rl != null) {
15069                    if (rl.curBroadcast != null) {
15070                        BroadcastRecord r = rl.curBroadcast;
15071                        final boolean doNext = finishReceiverLocked(
15072                                receiver.asBinder(), r.resultCode, r.resultData,
15073                                r.resultExtras, r.resultAbort);
15074                        if (doNext) {
15075                            doTrim = true;
15076                            r.queue.processNextBroadcast(false);
15077                        }
15078                    }
15079
15080                    if (rl.app != null) {
15081                        rl.app.receivers.remove(rl);
15082                    }
15083                    removeReceiverLocked(rl);
15084                    if (rl.linkedToDeath) {
15085                        rl.linkedToDeath = false;
15086                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15087                    }
15088                }
15089            }
15090
15091            // If we actually concluded any broadcasts, we might now be able
15092            // to trim the recipients' apps from our working set
15093            if (doTrim) {
15094                trimApplications();
15095                return;
15096            }
15097
15098        } finally {
15099            Binder.restoreCallingIdentity(origId);
15100        }
15101    }
15102
15103    void removeReceiverLocked(ReceiverList rl) {
15104        mRegisteredReceivers.remove(rl.receiver.asBinder());
15105        int N = rl.size();
15106        for (int i=0; i<N; i++) {
15107            mReceiverResolver.removeFilter(rl.get(i));
15108        }
15109    }
15110
15111    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15112        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15113            ProcessRecord r = mLruProcesses.get(i);
15114            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15115                try {
15116                    r.thread.dispatchPackageBroadcast(cmd, packages);
15117                } catch (RemoteException ex) {
15118                }
15119            }
15120        }
15121    }
15122
15123    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15124            int callingUid, int[] users) {
15125        List<ResolveInfo> receivers = null;
15126        try {
15127            HashSet<ComponentName> singleUserReceivers = null;
15128            boolean scannedFirstReceivers = false;
15129            for (int user : users) {
15130                // Skip users that have Shell restrictions
15131                if (callingUid == Process.SHELL_UID
15132                        && getUserManagerLocked().hasUserRestriction(
15133                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15134                    continue;
15135                }
15136                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15137                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15138                if (user != 0 && newReceivers != null) {
15139                    // If this is not the primary user, we need to check for
15140                    // any receivers that should be filtered out.
15141                    for (int i=0; i<newReceivers.size(); i++) {
15142                        ResolveInfo ri = newReceivers.get(i);
15143                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15144                            newReceivers.remove(i);
15145                            i--;
15146                        }
15147                    }
15148                }
15149                if (newReceivers != null && newReceivers.size() == 0) {
15150                    newReceivers = null;
15151                }
15152                if (receivers == null) {
15153                    receivers = newReceivers;
15154                } else if (newReceivers != null) {
15155                    // We need to concatenate the additional receivers
15156                    // found with what we have do far.  This would be easy,
15157                    // but we also need to de-dup any receivers that are
15158                    // singleUser.
15159                    if (!scannedFirstReceivers) {
15160                        // Collect any single user receivers we had already retrieved.
15161                        scannedFirstReceivers = true;
15162                        for (int i=0; i<receivers.size(); i++) {
15163                            ResolveInfo ri = receivers.get(i);
15164                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15165                                ComponentName cn = new ComponentName(
15166                                        ri.activityInfo.packageName, ri.activityInfo.name);
15167                                if (singleUserReceivers == null) {
15168                                    singleUserReceivers = new HashSet<ComponentName>();
15169                                }
15170                                singleUserReceivers.add(cn);
15171                            }
15172                        }
15173                    }
15174                    // Add the new results to the existing results, tracking
15175                    // and de-dupping single user receivers.
15176                    for (int i=0; i<newReceivers.size(); i++) {
15177                        ResolveInfo ri = newReceivers.get(i);
15178                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15179                            ComponentName cn = new ComponentName(
15180                                    ri.activityInfo.packageName, ri.activityInfo.name);
15181                            if (singleUserReceivers == null) {
15182                                singleUserReceivers = new HashSet<ComponentName>();
15183                            }
15184                            if (!singleUserReceivers.contains(cn)) {
15185                                singleUserReceivers.add(cn);
15186                                receivers.add(ri);
15187                            }
15188                        } else {
15189                            receivers.add(ri);
15190                        }
15191                    }
15192                }
15193            }
15194        } catch (RemoteException ex) {
15195            // pm is in same process, this will never happen.
15196        }
15197        return receivers;
15198    }
15199
15200    private final int broadcastIntentLocked(ProcessRecord callerApp,
15201            String callerPackage, Intent intent, String resolvedType,
15202            IIntentReceiver resultTo, int resultCode, String resultData,
15203            Bundle map, String requiredPermission, int appOp,
15204            boolean ordered, boolean sticky, int callingPid, int callingUid,
15205            int userId) {
15206        intent = new Intent(intent);
15207
15208        // By default broadcasts do not go to stopped apps.
15209        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15210
15211        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15212            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15213            + " ordered=" + ordered + " userid=" + userId);
15214        if ((resultTo != null) && !ordered) {
15215            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15216        }
15217
15218        userId = handleIncomingUser(callingPid, callingUid, userId,
15219                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15220
15221        // Make sure that the user who is receiving this broadcast is started.
15222        // If not, we will just skip it.
15223
15224        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15225            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15226                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15227                Slog.w(TAG, "Skipping broadcast of " + intent
15228                        + ": user " + userId + " is stopped");
15229                return ActivityManager.BROADCAST_SUCCESS;
15230            }
15231        }
15232
15233        /*
15234         * Prevent non-system code (defined here to be non-persistent
15235         * processes) from sending protected broadcasts.
15236         */
15237        int callingAppId = UserHandle.getAppId(callingUid);
15238        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15239            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15240            || callingAppId == Process.NFC_UID || callingUid == 0) {
15241            // Always okay.
15242        } else if (callerApp == null || !callerApp.persistent) {
15243            try {
15244                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15245                        intent.getAction())) {
15246                    String msg = "Permission Denial: not allowed to send broadcast "
15247                            + intent.getAction() + " from pid="
15248                            + callingPid + ", uid=" + callingUid;
15249                    Slog.w(TAG, msg);
15250                    throw new SecurityException(msg);
15251                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15252                    // Special case for compatibility: we don't want apps to send this,
15253                    // but historically it has not been protected and apps may be using it
15254                    // to poke their own app widget.  So, instead of making it protected,
15255                    // just limit it to the caller.
15256                    if (callerApp == null) {
15257                        String msg = "Permission Denial: not allowed to send broadcast "
15258                                + intent.getAction() + " from unknown caller.";
15259                        Slog.w(TAG, msg);
15260                        throw new SecurityException(msg);
15261                    } else if (intent.getComponent() != null) {
15262                        // They are good enough to send to an explicit component...  verify
15263                        // it is being sent to the calling app.
15264                        if (!intent.getComponent().getPackageName().equals(
15265                                callerApp.info.packageName)) {
15266                            String msg = "Permission Denial: not allowed to send broadcast "
15267                                    + intent.getAction() + " to "
15268                                    + intent.getComponent().getPackageName() + " from "
15269                                    + callerApp.info.packageName;
15270                            Slog.w(TAG, msg);
15271                            throw new SecurityException(msg);
15272                        }
15273                    } else {
15274                        // Limit broadcast to their own package.
15275                        intent.setPackage(callerApp.info.packageName);
15276                    }
15277                }
15278            } catch (RemoteException e) {
15279                Slog.w(TAG, "Remote exception", e);
15280                return ActivityManager.BROADCAST_SUCCESS;
15281            }
15282        }
15283
15284        // Handle special intents: if this broadcast is from the package
15285        // manager about a package being removed, we need to remove all of
15286        // its activities from the history stack.
15287        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15288                intent.getAction());
15289        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15290                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15291                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15292                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15293                || uidRemoved) {
15294            if (checkComponentPermission(
15295                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15296                    callingPid, callingUid, -1, true)
15297                    == PackageManager.PERMISSION_GRANTED) {
15298                if (uidRemoved) {
15299                    final Bundle intentExtras = intent.getExtras();
15300                    final int uid = intentExtras != null
15301                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15302                    if (uid >= 0) {
15303                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15304                        synchronized (bs) {
15305                            bs.removeUidStatsLocked(uid);
15306                        }
15307                        mAppOpsService.uidRemoved(uid);
15308                    }
15309                } else {
15310                    // If resources are unavailable just force stop all
15311                    // those packages and flush the attribute cache as well.
15312                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15313                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15314                        if (list != null && (list.length > 0)) {
15315                            for (String pkg : list) {
15316                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15317                                        "storage unmount");
15318                            }
15319                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15320                            sendPackageBroadcastLocked(
15321                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15322                        }
15323                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15324                            intent.getAction())) {
15325                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15326                    } else {
15327                        Uri data = intent.getData();
15328                        String ssp;
15329                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15330                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15331                                    intent.getAction());
15332                            boolean fullUninstall = removed &&
15333                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15334                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15335                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15336                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15337                                        false, fullUninstall, userId,
15338                                        removed ? "pkg removed" : "pkg changed");
15339                            }
15340                            if (removed) {
15341                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15342                                        new String[] {ssp}, userId);
15343                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15344                                    mAppOpsService.packageRemoved(
15345                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15346
15347                                    // Remove all permissions granted from/to this package
15348                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15349                                }
15350                            }
15351                        }
15352                    }
15353                }
15354            } else {
15355                String msg = "Permission Denial: " + intent.getAction()
15356                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15357                        + ", uid=" + callingUid + ")"
15358                        + " requires "
15359                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15360                Slog.w(TAG, msg);
15361                throw new SecurityException(msg);
15362            }
15363
15364        // Special case for adding a package: by default turn on compatibility
15365        // mode.
15366        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15367            Uri data = intent.getData();
15368            String ssp;
15369            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15370                mCompatModePackages.handlePackageAddedLocked(ssp,
15371                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15372            }
15373        }
15374
15375        /*
15376         * If this is the time zone changed action, queue up a message that will reset the timezone
15377         * of all currently running processes. This message will get queued up before the broadcast
15378         * happens.
15379         */
15380        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15381            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15382        }
15383
15384        /*
15385         * If the user set the time, let all running processes know.
15386         */
15387        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15388            final int is24Hour = intent.getBooleanExtra(
15389                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15390            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15391            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15392            synchronized (stats) {
15393                stats.noteCurrentTimeChangedLocked();
15394            }
15395        }
15396
15397        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15398            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15399        }
15400
15401        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15402            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15403            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15404        }
15405
15406        // Add to the sticky list if requested.
15407        if (sticky) {
15408            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15409                    callingPid, callingUid)
15410                    != PackageManager.PERMISSION_GRANTED) {
15411                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15412                        + callingPid + ", uid=" + callingUid
15413                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15414                Slog.w(TAG, msg);
15415                throw new SecurityException(msg);
15416            }
15417            if (requiredPermission != null) {
15418                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15419                        + " and enforce permission " + requiredPermission);
15420                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15421            }
15422            if (intent.getComponent() != null) {
15423                throw new SecurityException(
15424                        "Sticky broadcasts can't target a specific component");
15425            }
15426            // We use userId directly here, since the "all" target is maintained
15427            // as a separate set of sticky broadcasts.
15428            if (userId != UserHandle.USER_ALL) {
15429                // But first, if this is not a broadcast to all users, then
15430                // make sure it doesn't conflict with an existing broadcast to
15431                // all users.
15432                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15433                        UserHandle.USER_ALL);
15434                if (stickies != null) {
15435                    ArrayList<Intent> list = stickies.get(intent.getAction());
15436                    if (list != null) {
15437                        int N = list.size();
15438                        int i;
15439                        for (i=0; i<N; i++) {
15440                            if (intent.filterEquals(list.get(i))) {
15441                                throw new IllegalArgumentException(
15442                                        "Sticky broadcast " + intent + " for user "
15443                                        + userId + " conflicts with existing global broadcast");
15444                            }
15445                        }
15446                    }
15447                }
15448            }
15449            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15450            if (stickies == null) {
15451                stickies = new ArrayMap<String, ArrayList<Intent>>();
15452                mStickyBroadcasts.put(userId, stickies);
15453            }
15454            ArrayList<Intent> list = stickies.get(intent.getAction());
15455            if (list == null) {
15456                list = new ArrayList<Intent>();
15457                stickies.put(intent.getAction(), list);
15458            }
15459            int N = list.size();
15460            int i;
15461            for (i=0; i<N; i++) {
15462                if (intent.filterEquals(list.get(i))) {
15463                    // This sticky already exists, replace it.
15464                    list.set(i, new Intent(intent));
15465                    break;
15466                }
15467            }
15468            if (i >= N) {
15469                list.add(new Intent(intent));
15470            }
15471        }
15472
15473        int[] users;
15474        if (userId == UserHandle.USER_ALL) {
15475            // Caller wants broadcast to go to all started users.
15476            users = mStartedUserArray;
15477        } else {
15478            // Caller wants broadcast to go to one specific user.
15479            users = new int[] {userId};
15480        }
15481
15482        // Figure out who all will receive this broadcast.
15483        List receivers = null;
15484        List<BroadcastFilter> registeredReceivers = null;
15485        // Need to resolve the intent to interested receivers...
15486        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15487                 == 0) {
15488            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15489        }
15490        if (intent.getComponent() == null) {
15491            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15492                // Query one target user at a time, excluding shell-restricted users
15493                UserManagerService ums = getUserManagerLocked();
15494                for (int i = 0; i < users.length; i++) {
15495                    if (ums.hasUserRestriction(
15496                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15497                        continue;
15498                    }
15499                    List<BroadcastFilter> registeredReceiversForUser =
15500                            mReceiverResolver.queryIntent(intent,
15501                                    resolvedType, false, users[i]);
15502                    if (registeredReceivers == null) {
15503                        registeredReceivers = registeredReceiversForUser;
15504                    } else if (registeredReceiversForUser != null) {
15505                        registeredReceivers.addAll(registeredReceiversForUser);
15506                    }
15507                }
15508            } else {
15509                registeredReceivers = mReceiverResolver.queryIntent(intent,
15510                        resolvedType, false, userId);
15511            }
15512        }
15513
15514        final boolean replacePending =
15515                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15516
15517        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15518                + " replacePending=" + replacePending);
15519
15520        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15521        if (!ordered && NR > 0) {
15522            // If we are not serializing this broadcast, then send the
15523            // registered receivers separately so they don't wait for the
15524            // components to be launched.
15525            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15526            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15527                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15528                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15529                    ordered, sticky, false, userId);
15530            if (DEBUG_BROADCAST) Slog.v(
15531                    TAG, "Enqueueing parallel broadcast " + r);
15532            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15533            if (!replaced) {
15534                queue.enqueueParallelBroadcastLocked(r);
15535                queue.scheduleBroadcastsLocked();
15536            }
15537            registeredReceivers = null;
15538            NR = 0;
15539        }
15540
15541        // Merge into one list.
15542        int ir = 0;
15543        if (receivers != null) {
15544            // A special case for PACKAGE_ADDED: do not allow the package
15545            // being added to see this broadcast.  This prevents them from
15546            // using this as a back door to get run as soon as they are
15547            // installed.  Maybe in the future we want to have a special install
15548            // broadcast or such for apps, but we'd like to deliberately make
15549            // this decision.
15550            String skipPackages[] = null;
15551            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15552                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15553                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15554                Uri data = intent.getData();
15555                if (data != null) {
15556                    String pkgName = data.getSchemeSpecificPart();
15557                    if (pkgName != null) {
15558                        skipPackages = new String[] { pkgName };
15559                    }
15560                }
15561            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15562                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15563            }
15564            if (skipPackages != null && (skipPackages.length > 0)) {
15565                for (String skipPackage : skipPackages) {
15566                    if (skipPackage != null) {
15567                        int NT = receivers.size();
15568                        for (int it=0; it<NT; it++) {
15569                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15570                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15571                                receivers.remove(it);
15572                                it--;
15573                                NT--;
15574                            }
15575                        }
15576                    }
15577                }
15578            }
15579
15580            int NT = receivers != null ? receivers.size() : 0;
15581            int it = 0;
15582            ResolveInfo curt = null;
15583            BroadcastFilter curr = null;
15584            while (it < NT && ir < NR) {
15585                if (curt == null) {
15586                    curt = (ResolveInfo)receivers.get(it);
15587                }
15588                if (curr == null) {
15589                    curr = registeredReceivers.get(ir);
15590                }
15591                if (curr.getPriority() >= curt.priority) {
15592                    // Insert this broadcast record into the final list.
15593                    receivers.add(it, curr);
15594                    ir++;
15595                    curr = null;
15596                    it++;
15597                    NT++;
15598                } else {
15599                    // Skip to the next ResolveInfo in the final list.
15600                    it++;
15601                    curt = null;
15602                }
15603            }
15604        }
15605        while (ir < NR) {
15606            if (receivers == null) {
15607                receivers = new ArrayList();
15608            }
15609            receivers.add(registeredReceivers.get(ir));
15610            ir++;
15611        }
15612
15613        if ((receivers != null && receivers.size() > 0)
15614                || resultTo != null) {
15615            BroadcastQueue queue = broadcastQueueForIntent(intent);
15616            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15617                    callerPackage, callingPid, callingUid, resolvedType,
15618                    requiredPermission, appOp, receivers, resultTo, resultCode,
15619                    resultData, map, ordered, sticky, false, userId);
15620            if (DEBUG_BROADCAST) Slog.v(
15621                    TAG, "Enqueueing ordered broadcast " + r
15622                    + ": prev had " + queue.mOrderedBroadcasts.size());
15623            if (DEBUG_BROADCAST) {
15624                int seq = r.intent.getIntExtra("seq", -1);
15625                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15626            }
15627            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15628            if (!replaced) {
15629                queue.enqueueOrderedBroadcastLocked(r);
15630                queue.scheduleBroadcastsLocked();
15631            }
15632        }
15633
15634        return ActivityManager.BROADCAST_SUCCESS;
15635    }
15636
15637    final Intent verifyBroadcastLocked(Intent intent) {
15638        // Refuse possible leaked file descriptors
15639        if (intent != null && intent.hasFileDescriptors() == true) {
15640            throw new IllegalArgumentException("File descriptors passed in Intent");
15641        }
15642
15643        int flags = intent.getFlags();
15644
15645        if (!mProcessesReady) {
15646            // if the caller really truly claims to know what they're doing, go
15647            // ahead and allow the broadcast without launching any receivers
15648            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15649                intent = new Intent(intent);
15650                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15651            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15652                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15653                        + " before boot completion");
15654                throw new IllegalStateException("Cannot broadcast before boot completed");
15655            }
15656        }
15657
15658        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15659            throw new IllegalArgumentException(
15660                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15661        }
15662
15663        return intent;
15664    }
15665
15666    public final int broadcastIntent(IApplicationThread caller,
15667            Intent intent, String resolvedType, IIntentReceiver resultTo,
15668            int resultCode, String resultData, Bundle map,
15669            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15670        enforceNotIsolatedCaller("broadcastIntent");
15671        synchronized(this) {
15672            intent = verifyBroadcastLocked(intent);
15673
15674            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15675            final int callingPid = Binder.getCallingPid();
15676            final int callingUid = Binder.getCallingUid();
15677            final long origId = Binder.clearCallingIdentity();
15678            int res = broadcastIntentLocked(callerApp,
15679                    callerApp != null ? callerApp.info.packageName : null,
15680                    intent, resolvedType, resultTo,
15681                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15682                    callingPid, callingUid, userId);
15683            Binder.restoreCallingIdentity(origId);
15684            return res;
15685        }
15686    }
15687
15688    int broadcastIntentInPackage(String packageName, int uid,
15689            Intent intent, String resolvedType, IIntentReceiver resultTo,
15690            int resultCode, String resultData, Bundle map,
15691            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15692        synchronized(this) {
15693            intent = verifyBroadcastLocked(intent);
15694
15695            final long origId = Binder.clearCallingIdentity();
15696            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15697                    resultTo, resultCode, resultData, map, requiredPermission,
15698                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15699            Binder.restoreCallingIdentity(origId);
15700            return res;
15701        }
15702    }
15703
15704    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15705        // Refuse possible leaked file descriptors
15706        if (intent != null && intent.hasFileDescriptors() == true) {
15707            throw new IllegalArgumentException("File descriptors passed in Intent");
15708        }
15709
15710        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15711                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15712
15713        synchronized(this) {
15714            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15715                    != PackageManager.PERMISSION_GRANTED) {
15716                String msg = "Permission Denial: unbroadcastIntent() from pid="
15717                        + Binder.getCallingPid()
15718                        + ", uid=" + Binder.getCallingUid()
15719                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15720                Slog.w(TAG, msg);
15721                throw new SecurityException(msg);
15722            }
15723            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15724            if (stickies != null) {
15725                ArrayList<Intent> list = stickies.get(intent.getAction());
15726                if (list != null) {
15727                    int N = list.size();
15728                    int i;
15729                    for (i=0; i<N; i++) {
15730                        if (intent.filterEquals(list.get(i))) {
15731                            list.remove(i);
15732                            break;
15733                        }
15734                    }
15735                    if (list.size() <= 0) {
15736                        stickies.remove(intent.getAction());
15737                    }
15738                }
15739                if (stickies.size() <= 0) {
15740                    mStickyBroadcasts.remove(userId);
15741                }
15742            }
15743        }
15744    }
15745
15746    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15747            String resultData, Bundle resultExtras, boolean resultAbort) {
15748        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15749        if (r == null) {
15750            Slog.w(TAG, "finishReceiver called but not found on queue");
15751            return false;
15752        }
15753
15754        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15755    }
15756
15757    void backgroundServicesFinishedLocked(int userId) {
15758        for (BroadcastQueue queue : mBroadcastQueues) {
15759            queue.backgroundServicesFinishedLocked(userId);
15760        }
15761    }
15762
15763    public void finishReceiver(IBinder who, int resultCode, String resultData,
15764            Bundle resultExtras, boolean resultAbort) {
15765        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15766
15767        // Refuse possible leaked file descriptors
15768        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15769            throw new IllegalArgumentException("File descriptors passed in Bundle");
15770        }
15771
15772        final long origId = Binder.clearCallingIdentity();
15773        try {
15774            boolean doNext = false;
15775            BroadcastRecord r;
15776
15777            synchronized(this) {
15778                r = broadcastRecordForReceiverLocked(who);
15779                if (r != null) {
15780                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15781                        resultData, resultExtras, resultAbort, true);
15782                }
15783            }
15784
15785            if (doNext) {
15786                r.queue.processNextBroadcast(false);
15787            }
15788            trimApplications();
15789        } finally {
15790            Binder.restoreCallingIdentity(origId);
15791        }
15792    }
15793
15794    // =========================================================
15795    // INSTRUMENTATION
15796    // =========================================================
15797
15798    public boolean startInstrumentation(ComponentName className,
15799            String profileFile, int flags, Bundle arguments,
15800            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15801            int userId, String abiOverride) {
15802        enforceNotIsolatedCaller("startInstrumentation");
15803        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15804                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15805        // Refuse possible leaked file descriptors
15806        if (arguments != null && arguments.hasFileDescriptors()) {
15807            throw new IllegalArgumentException("File descriptors passed in Bundle");
15808        }
15809
15810        synchronized(this) {
15811            InstrumentationInfo ii = null;
15812            ApplicationInfo ai = null;
15813            try {
15814                ii = mContext.getPackageManager().getInstrumentationInfo(
15815                    className, STOCK_PM_FLAGS);
15816                ai = AppGlobals.getPackageManager().getApplicationInfo(
15817                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15818            } catch (PackageManager.NameNotFoundException e) {
15819            } catch (RemoteException e) {
15820            }
15821            if (ii == null) {
15822                reportStartInstrumentationFailure(watcher, className,
15823                        "Unable to find instrumentation info for: " + className);
15824                return false;
15825            }
15826            if (ai == null) {
15827                reportStartInstrumentationFailure(watcher, className,
15828                        "Unable to find instrumentation target package: " + ii.targetPackage);
15829                return false;
15830            }
15831
15832            int match = mContext.getPackageManager().checkSignatures(
15833                    ii.targetPackage, ii.packageName);
15834            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15835                String msg = "Permission Denial: starting instrumentation "
15836                        + className + " from pid="
15837                        + Binder.getCallingPid()
15838                        + ", uid=" + Binder.getCallingPid()
15839                        + " not allowed because package " + ii.packageName
15840                        + " does not have a signature matching the target "
15841                        + ii.targetPackage;
15842                reportStartInstrumentationFailure(watcher, className, msg);
15843                throw new SecurityException(msg);
15844            }
15845
15846            final long origId = Binder.clearCallingIdentity();
15847            // Instrumentation can kill and relaunch even persistent processes
15848            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15849                    "start instr");
15850            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15851            app.instrumentationClass = className;
15852            app.instrumentationInfo = ai;
15853            app.instrumentationProfileFile = profileFile;
15854            app.instrumentationArguments = arguments;
15855            app.instrumentationWatcher = watcher;
15856            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15857            app.instrumentationResultClass = className;
15858            Binder.restoreCallingIdentity(origId);
15859        }
15860
15861        return true;
15862    }
15863
15864    /**
15865     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15866     * error to the logs, but if somebody is watching, send the report there too.  This enables
15867     * the "am" command to report errors with more information.
15868     *
15869     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15870     * @param cn The component name of the instrumentation.
15871     * @param report The error report.
15872     */
15873    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15874            ComponentName cn, String report) {
15875        Slog.w(TAG, report);
15876        try {
15877            if (watcher != null) {
15878                Bundle results = new Bundle();
15879                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15880                results.putString("Error", report);
15881                watcher.instrumentationStatus(cn, -1, results);
15882            }
15883        } catch (RemoteException e) {
15884            Slog.w(TAG, e);
15885        }
15886    }
15887
15888    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15889        if (app.instrumentationWatcher != null) {
15890            try {
15891                // NOTE:  IInstrumentationWatcher *must* be oneway here
15892                app.instrumentationWatcher.instrumentationFinished(
15893                    app.instrumentationClass,
15894                    resultCode,
15895                    results);
15896            } catch (RemoteException e) {
15897            }
15898        }
15899        if (app.instrumentationUiAutomationConnection != null) {
15900            try {
15901                app.instrumentationUiAutomationConnection.shutdown();
15902            } catch (RemoteException re) {
15903                /* ignore */
15904            }
15905            // Only a UiAutomation can set this flag and now that
15906            // it is finished we make sure it is reset to its default.
15907            mUserIsMonkey = false;
15908        }
15909        app.instrumentationWatcher = null;
15910        app.instrumentationUiAutomationConnection = null;
15911        app.instrumentationClass = null;
15912        app.instrumentationInfo = null;
15913        app.instrumentationProfileFile = null;
15914        app.instrumentationArguments = null;
15915
15916        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15917                "finished inst");
15918    }
15919
15920    public void finishInstrumentation(IApplicationThread target,
15921            int resultCode, Bundle results) {
15922        int userId = UserHandle.getCallingUserId();
15923        // Refuse possible leaked file descriptors
15924        if (results != null && results.hasFileDescriptors()) {
15925            throw new IllegalArgumentException("File descriptors passed in Intent");
15926        }
15927
15928        synchronized(this) {
15929            ProcessRecord app = getRecordForAppLocked(target);
15930            if (app == null) {
15931                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15932                return;
15933            }
15934            final long origId = Binder.clearCallingIdentity();
15935            finishInstrumentationLocked(app, resultCode, results);
15936            Binder.restoreCallingIdentity(origId);
15937        }
15938    }
15939
15940    // =========================================================
15941    // CONFIGURATION
15942    // =========================================================
15943
15944    public ConfigurationInfo getDeviceConfigurationInfo() {
15945        ConfigurationInfo config = new ConfigurationInfo();
15946        synchronized (this) {
15947            config.reqTouchScreen = mConfiguration.touchscreen;
15948            config.reqKeyboardType = mConfiguration.keyboard;
15949            config.reqNavigation = mConfiguration.navigation;
15950            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15951                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15952                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15953            }
15954            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15955                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15956                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15957            }
15958            config.reqGlEsVersion = GL_ES_VERSION;
15959        }
15960        return config;
15961    }
15962
15963    ActivityStack getFocusedStack() {
15964        return mStackSupervisor.getFocusedStack();
15965    }
15966
15967    public Configuration getConfiguration() {
15968        Configuration ci;
15969        synchronized(this) {
15970            ci = new Configuration(mConfiguration);
15971        }
15972        return ci;
15973    }
15974
15975    public void updatePersistentConfiguration(Configuration values) {
15976        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15977                "updateConfiguration()");
15978        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15979                "updateConfiguration()");
15980        if (values == null) {
15981            throw new NullPointerException("Configuration must not be null");
15982        }
15983
15984        synchronized(this) {
15985            final long origId = Binder.clearCallingIdentity();
15986            updateConfigurationLocked(values, null, true, false);
15987            Binder.restoreCallingIdentity(origId);
15988        }
15989    }
15990
15991    public void updateConfiguration(Configuration values) {
15992        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15993                "updateConfiguration()");
15994
15995        synchronized(this) {
15996            if (values == null && mWindowManager != null) {
15997                // sentinel: fetch the current configuration from the window manager
15998                values = mWindowManager.computeNewConfiguration();
15999            }
16000
16001            if (mWindowManager != null) {
16002                mProcessList.applyDisplaySize(mWindowManager);
16003            }
16004
16005            final long origId = Binder.clearCallingIdentity();
16006            if (values != null) {
16007                Settings.System.clearConfiguration(values);
16008            }
16009            updateConfigurationLocked(values, null, false, false);
16010            Binder.restoreCallingIdentity(origId);
16011        }
16012    }
16013
16014    /**
16015     * Do either or both things: (1) change the current configuration, and (2)
16016     * make sure the given activity is running with the (now) current
16017     * configuration.  Returns true if the activity has been left running, or
16018     * false if <var>starting</var> is being destroyed to match the new
16019     * configuration.
16020     * @param persistent TODO
16021     */
16022    boolean updateConfigurationLocked(Configuration values,
16023            ActivityRecord starting, boolean persistent, boolean initLocale) {
16024        int changes = 0;
16025
16026        if (values != null) {
16027            Configuration newConfig = new Configuration(mConfiguration);
16028            changes = newConfig.updateFrom(values);
16029            if (changes != 0) {
16030                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16031                    Slog.i(TAG, "Updating configuration to: " + values);
16032                }
16033
16034                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16035
16036                if (values.locale != null && !initLocale) {
16037                    saveLocaleLocked(values.locale,
16038                                     !values.locale.equals(mConfiguration.locale),
16039                                     values.userSetLocale);
16040                }
16041
16042                mConfigurationSeq++;
16043                if (mConfigurationSeq <= 0) {
16044                    mConfigurationSeq = 1;
16045                }
16046                newConfig.seq = mConfigurationSeq;
16047                mConfiguration = newConfig;
16048                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16049                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16050                //mUsageStatsService.noteStartConfig(newConfig);
16051
16052                final Configuration configCopy = new Configuration(mConfiguration);
16053
16054                // TODO: If our config changes, should we auto dismiss any currently
16055                // showing dialogs?
16056                mShowDialogs = shouldShowDialogs(newConfig);
16057
16058                AttributeCache ac = AttributeCache.instance();
16059                if (ac != null) {
16060                    ac.updateConfiguration(configCopy);
16061                }
16062
16063                // Make sure all resources in our process are updated
16064                // right now, so that anyone who is going to retrieve
16065                // resource values after we return will be sure to get
16066                // the new ones.  This is especially important during
16067                // boot, where the first config change needs to guarantee
16068                // all resources have that config before following boot
16069                // code is executed.
16070                mSystemThread.applyConfigurationToResources(configCopy);
16071
16072                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16073                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16074                    msg.obj = new Configuration(configCopy);
16075                    mHandler.sendMessage(msg);
16076                }
16077
16078                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16079                    ProcessRecord app = mLruProcesses.get(i);
16080                    try {
16081                        if (app.thread != null) {
16082                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16083                                    + app.processName + " new config " + mConfiguration);
16084                            app.thread.scheduleConfigurationChanged(configCopy);
16085                        }
16086                    } catch (Exception e) {
16087                    }
16088                }
16089                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16090                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16091                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16092                        | Intent.FLAG_RECEIVER_FOREGROUND);
16093                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16094                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16095                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16096                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16097                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16098                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16099                    broadcastIntentLocked(null, null, intent,
16100                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16101                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16102                }
16103            }
16104        }
16105
16106        boolean kept = true;
16107        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16108        // mainStack is null during startup.
16109        if (mainStack != null) {
16110            if (changes != 0 && starting == null) {
16111                // If the configuration changed, and the caller is not already
16112                // in the process of starting an activity, then find the top
16113                // activity to check if its configuration needs to change.
16114                starting = mainStack.topRunningActivityLocked(null);
16115            }
16116
16117            if (starting != null) {
16118                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16119                // And we need to make sure at this point that all other activities
16120                // are made visible with the correct configuration.
16121                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16122            }
16123        }
16124
16125        if (values != null && mWindowManager != null) {
16126            mWindowManager.setNewConfiguration(mConfiguration);
16127        }
16128
16129        return kept;
16130    }
16131
16132    /**
16133     * Decide based on the configuration whether we should shouw the ANR,
16134     * crash, etc dialogs.  The idea is that if there is no affordnace to
16135     * press the on-screen buttons, we shouldn't show the dialog.
16136     *
16137     * A thought: SystemUI might also want to get told about this, the Power
16138     * dialog / global actions also might want different behaviors.
16139     */
16140    private static final boolean shouldShowDialogs(Configuration config) {
16141        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16142                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16143    }
16144
16145    /**
16146     * Save the locale.  You must be inside a synchronized (this) block.
16147     */
16148    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16149        if(isDiff) {
16150            SystemProperties.set("user.language", l.getLanguage());
16151            SystemProperties.set("user.region", l.getCountry());
16152        }
16153
16154        if(isPersist) {
16155            SystemProperties.set("persist.sys.language", l.getLanguage());
16156            SystemProperties.set("persist.sys.country", l.getCountry());
16157            SystemProperties.set("persist.sys.localevar", l.getVariant());
16158        }
16159    }
16160
16161    @Override
16162    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16163        synchronized (this) {
16164            ActivityRecord srec = ActivityRecord.forToken(token);
16165            if (srec.task != null && srec.task.stack != null) {
16166                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16167            }
16168        }
16169        return false;
16170    }
16171
16172    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16173            Intent resultData) {
16174
16175        synchronized (this) {
16176            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16177            if (stack != null) {
16178                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16179            }
16180            return false;
16181        }
16182    }
16183
16184    public int getLaunchedFromUid(IBinder activityToken) {
16185        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16186        if (srec == null) {
16187            return -1;
16188        }
16189        return srec.launchedFromUid;
16190    }
16191
16192    public String getLaunchedFromPackage(IBinder activityToken) {
16193        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16194        if (srec == null) {
16195            return null;
16196        }
16197        return srec.launchedFromPackage;
16198    }
16199
16200    // =========================================================
16201    // LIFETIME MANAGEMENT
16202    // =========================================================
16203
16204    // Returns which broadcast queue the app is the current [or imminent] receiver
16205    // on, or 'null' if the app is not an active broadcast recipient.
16206    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16207        BroadcastRecord r = app.curReceiver;
16208        if (r != null) {
16209            return r.queue;
16210        }
16211
16212        // It's not the current receiver, but it might be starting up to become one
16213        synchronized (this) {
16214            for (BroadcastQueue queue : mBroadcastQueues) {
16215                r = queue.mPendingBroadcast;
16216                if (r != null && r.curApp == app) {
16217                    // found it; report which queue it's in
16218                    return queue;
16219                }
16220            }
16221        }
16222
16223        return null;
16224    }
16225
16226    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16227            boolean doingAll, long now) {
16228        if (mAdjSeq == app.adjSeq) {
16229            // This adjustment has already been computed.
16230            return app.curRawAdj;
16231        }
16232
16233        if (app.thread == null) {
16234            app.adjSeq = mAdjSeq;
16235            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16236            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16237            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16238        }
16239
16240        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16241        app.adjSource = null;
16242        app.adjTarget = null;
16243        app.empty = false;
16244        app.cached = false;
16245
16246        final int activitiesSize = app.activities.size();
16247
16248        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16249            // The max adjustment doesn't allow this app to be anything
16250            // below foreground, so it is not worth doing work for it.
16251            app.adjType = "fixed";
16252            app.adjSeq = mAdjSeq;
16253            app.curRawAdj = app.maxAdj;
16254            app.foregroundActivities = false;
16255            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16256            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16257            // System processes can do UI, and when they do we want to have
16258            // them trim their memory after the user leaves the UI.  To
16259            // facilitate this, here we need to determine whether or not it
16260            // is currently showing UI.
16261            app.systemNoUi = true;
16262            if (app == TOP_APP) {
16263                app.systemNoUi = false;
16264            } else if (activitiesSize > 0) {
16265                for (int j = 0; j < activitiesSize; j++) {
16266                    final ActivityRecord r = app.activities.get(j);
16267                    if (r.visible) {
16268                        app.systemNoUi = false;
16269                    }
16270                }
16271            }
16272            if (!app.systemNoUi) {
16273                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16274            }
16275            return (app.curAdj=app.maxAdj);
16276        }
16277
16278        app.systemNoUi = false;
16279
16280        // Determine the importance of the process, starting with most
16281        // important to least, and assign an appropriate OOM adjustment.
16282        int adj;
16283        int schedGroup;
16284        int procState;
16285        boolean foregroundActivities = false;
16286        BroadcastQueue queue;
16287        if (app == TOP_APP) {
16288            // The last app on the list is the foreground app.
16289            adj = ProcessList.FOREGROUND_APP_ADJ;
16290            schedGroup = Process.THREAD_GROUP_DEFAULT;
16291            app.adjType = "top-activity";
16292            foregroundActivities = true;
16293            procState = ActivityManager.PROCESS_STATE_TOP;
16294        } else if (app.instrumentationClass != null) {
16295            // Don't want to kill running instrumentation.
16296            adj = ProcessList.FOREGROUND_APP_ADJ;
16297            schedGroup = Process.THREAD_GROUP_DEFAULT;
16298            app.adjType = "instrumentation";
16299            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16300        } else if ((queue = isReceivingBroadcast(app)) != null) {
16301            // An app that is currently receiving a broadcast also
16302            // counts as being in the foreground for OOM killer purposes.
16303            // It's placed in a sched group based on the nature of the
16304            // broadcast as reflected by which queue it's active in.
16305            adj = ProcessList.FOREGROUND_APP_ADJ;
16306            schedGroup = (queue == mFgBroadcastQueue)
16307                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16308            app.adjType = "broadcast";
16309            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16310        } else if (app.executingServices.size() > 0) {
16311            // An app that is currently executing a service callback also
16312            // counts as being in the foreground.
16313            adj = ProcessList.FOREGROUND_APP_ADJ;
16314            schedGroup = app.execServicesFg ?
16315                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16316            app.adjType = "exec-service";
16317            procState = ActivityManager.PROCESS_STATE_SERVICE;
16318            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16319        } else {
16320            // As far as we know the process is empty.  We may change our mind later.
16321            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16322            // At this point we don't actually know the adjustment.  Use the cached adj
16323            // value that the caller wants us to.
16324            adj = cachedAdj;
16325            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16326            app.cached = true;
16327            app.empty = true;
16328            app.adjType = "cch-empty";
16329        }
16330
16331        // Examine all activities if not already foreground.
16332        if (!foregroundActivities && activitiesSize > 0) {
16333            for (int j = 0; j < activitiesSize; j++) {
16334                final ActivityRecord r = app.activities.get(j);
16335                if (r.app != app) {
16336                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16337                            + app + "?!?");
16338                    continue;
16339                }
16340                if (r.visible) {
16341                    // App has a visible activity; only upgrade adjustment.
16342                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16343                        adj = ProcessList.VISIBLE_APP_ADJ;
16344                        app.adjType = "visible";
16345                    }
16346                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16347                        procState = ActivityManager.PROCESS_STATE_TOP;
16348                    }
16349                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16350                    app.cached = false;
16351                    app.empty = false;
16352                    foregroundActivities = true;
16353                    break;
16354                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16355                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16356                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16357                        app.adjType = "pausing";
16358                    }
16359                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16360                        procState = ActivityManager.PROCESS_STATE_TOP;
16361                    }
16362                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16363                    app.cached = false;
16364                    app.empty = false;
16365                    foregroundActivities = true;
16366                } else if (r.state == ActivityState.STOPPING) {
16367                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16368                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16369                        app.adjType = "stopping";
16370                    }
16371                    // For the process state, we will at this point consider the
16372                    // process to be cached.  It will be cached either as an activity
16373                    // or empty depending on whether the activity is finishing.  We do
16374                    // this so that we can treat the process as cached for purposes of
16375                    // memory trimming (determing current memory level, trim command to
16376                    // send to process) since there can be an arbitrary number of stopping
16377                    // processes and they should soon all go into the cached state.
16378                    if (!r.finishing) {
16379                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16380                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16381                        }
16382                    }
16383                    app.cached = false;
16384                    app.empty = false;
16385                    foregroundActivities = true;
16386                } else {
16387                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16388                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16389                        app.adjType = "cch-act";
16390                    }
16391                }
16392            }
16393        }
16394
16395        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16396            if (app.foregroundServices) {
16397                // The user is aware of this app, so make it visible.
16398                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16399                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16400                app.cached = false;
16401                app.adjType = "fg-service";
16402                schedGroup = Process.THREAD_GROUP_DEFAULT;
16403            } else if (app.forcingToForeground != null) {
16404                // The user is aware of this app, so make it visible.
16405                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16406                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16407                app.cached = false;
16408                app.adjType = "force-fg";
16409                app.adjSource = app.forcingToForeground;
16410                schedGroup = Process.THREAD_GROUP_DEFAULT;
16411            }
16412        }
16413
16414        if (app == mHeavyWeightProcess) {
16415            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16416                // We don't want to kill the current heavy-weight process.
16417                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16418                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16419                app.cached = false;
16420                app.adjType = "heavy";
16421            }
16422            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16423                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16424            }
16425        }
16426
16427        if (app == mHomeProcess) {
16428            if (adj > ProcessList.HOME_APP_ADJ) {
16429                // This process is hosting what we currently consider to be the
16430                // home app, so we don't want to let it go into the background.
16431                adj = ProcessList.HOME_APP_ADJ;
16432                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16433                app.cached = false;
16434                app.adjType = "home";
16435            }
16436            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16437                procState = ActivityManager.PROCESS_STATE_HOME;
16438            }
16439        }
16440
16441        if (app == mPreviousProcess && app.activities.size() > 0) {
16442            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16443                // This was the previous process that showed UI to the user.
16444                // We want to try to keep it around more aggressively, to give
16445                // a good experience around switching between two apps.
16446                adj = ProcessList.PREVIOUS_APP_ADJ;
16447                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16448                app.cached = false;
16449                app.adjType = "previous";
16450            }
16451            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16452                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16453            }
16454        }
16455
16456        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16457                + " reason=" + app.adjType);
16458
16459        // By default, we use the computed adjustment.  It may be changed if
16460        // there are applications dependent on our services or providers, but
16461        // this gives us a baseline and makes sure we don't get into an
16462        // infinite recursion.
16463        app.adjSeq = mAdjSeq;
16464        app.curRawAdj = adj;
16465        app.hasStartedServices = false;
16466
16467        if (mBackupTarget != null && app == mBackupTarget.app) {
16468            // If possible we want to avoid killing apps while they're being backed up
16469            if (adj > ProcessList.BACKUP_APP_ADJ) {
16470                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16471                adj = ProcessList.BACKUP_APP_ADJ;
16472                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16473                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16474                }
16475                app.adjType = "backup";
16476                app.cached = false;
16477            }
16478            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16479                procState = ActivityManager.PROCESS_STATE_BACKUP;
16480            }
16481        }
16482
16483        boolean mayBeTop = false;
16484
16485        for (int is = app.services.size()-1;
16486                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16487                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16488                        || procState > ActivityManager.PROCESS_STATE_TOP);
16489                is--) {
16490            ServiceRecord s = app.services.valueAt(is);
16491            if (s.startRequested) {
16492                app.hasStartedServices = true;
16493                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16494                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16495                }
16496                if (app.hasShownUi && app != mHomeProcess) {
16497                    // If this process has shown some UI, let it immediately
16498                    // go to the LRU list because it may be pretty heavy with
16499                    // UI stuff.  We'll tag it with a label just to help
16500                    // debug and understand what is going on.
16501                    if (adj > ProcessList.SERVICE_ADJ) {
16502                        app.adjType = "cch-started-ui-services";
16503                    }
16504                } else {
16505                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16506                        // This service has seen some activity within
16507                        // recent memory, so we will keep its process ahead
16508                        // of the background processes.
16509                        if (adj > ProcessList.SERVICE_ADJ) {
16510                            adj = ProcessList.SERVICE_ADJ;
16511                            app.adjType = "started-services";
16512                            app.cached = false;
16513                        }
16514                    }
16515                    // If we have let the service slide into the background
16516                    // state, still have some text describing what it is doing
16517                    // even though the service no longer has an impact.
16518                    if (adj > ProcessList.SERVICE_ADJ) {
16519                        app.adjType = "cch-started-services";
16520                    }
16521                }
16522            }
16523            for (int conni = s.connections.size()-1;
16524                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16525                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16526                            || procState > ActivityManager.PROCESS_STATE_TOP);
16527                    conni--) {
16528                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16529                for (int i = 0;
16530                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16531                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16532                                || procState > ActivityManager.PROCESS_STATE_TOP);
16533                        i++) {
16534                    // XXX should compute this based on the max of
16535                    // all connected clients.
16536                    ConnectionRecord cr = clist.get(i);
16537                    if (cr.binding.client == app) {
16538                        // Binding to ourself is not interesting.
16539                        continue;
16540                    }
16541                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16542                        ProcessRecord client = cr.binding.client;
16543                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16544                                TOP_APP, doingAll, now);
16545                        int clientProcState = client.curProcState;
16546                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16547                            // If the other app is cached for any reason, for purposes here
16548                            // we are going to consider it empty.  The specific cached state
16549                            // doesn't propagate except under certain conditions.
16550                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16551                        }
16552                        String adjType = null;
16553                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16554                            // Not doing bind OOM management, so treat
16555                            // this guy more like a started service.
16556                            if (app.hasShownUi && app != mHomeProcess) {
16557                                // If this process has shown some UI, let it immediately
16558                                // go to the LRU list because it may be pretty heavy with
16559                                // UI stuff.  We'll tag it with a label just to help
16560                                // debug and understand what is going on.
16561                                if (adj > clientAdj) {
16562                                    adjType = "cch-bound-ui-services";
16563                                }
16564                                app.cached = false;
16565                                clientAdj = adj;
16566                                clientProcState = procState;
16567                            } else {
16568                                if (now >= (s.lastActivity
16569                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16570                                    // This service has not seen activity within
16571                                    // recent memory, so allow it to drop to the
16572                                    // LRU list if there is no other reason to keep
16573                                    // it around.  We'll also tag it with a label just
16574                                    // to help debug and undertand what is going on.
16575                                    if (adj > clientAdj) {
16576                                        adjType = "cch-bound-services";
16577                                    }
16578                                    clientAdj = adj;
16579                                }
16580                            }
16581                        }
16582                        if (adj > clientAdj) {
16583                            // If this process has recently shown UI, and
16584                            // the process that is binding to it is less
16585                            // important than being visible, then we don't
16586                            // care about the binding as much as we care
16587                            // about letting this process get into the LRU
16588                            // list to be killed and restarted if needed for
16589                            // memory.
16590                            if (app.hasShownUi && app != mHomeProcess
16591                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16592                                adjType = "cch-bound-ui-services";
16593                            } else {
16594                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16595                                        |Context.BIND_IMPORTANT)) != 0) {
16596                                    adj = clientAdj;
16597                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16598                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16599                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16600                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16601                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16602                                    adj = clientAdj;
16603                                } else {
16604                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16605                                        adj = ProcessList.VISIBLE_APP_ADJ;
16606                                    }
16607                                }
16608                                if (!client.cached) {
16609                                    app.cached = false;
16610                                }
16611                                adjType = "service";
16612                            }
16613                        }
16614                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16615                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16616                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16617                            }
16618                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16619                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16620                                    // Special handling of clients who are in the top state.
16621                                    // We *may* want to consider this process to be in the
16622                                    // top state as well, but only if there is not another
16623                                    // reason for it to be running.  Being on the top is a
16624                                    // special state, meaning you are specifically running
16625                                    // for the current top app.  If the process is already
16626                                    // running in the background for some other reason, it
16627                                    // is more important to continue considering it to be
16628                                    // in the background state.
16629                                    mayBeTop = true;
16630                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16631                                } else {
16632                                    // Special handling for above-top states (persistent
16633                                    // processes).  These should not bring the current process
16634                                    // into the top state, since they are not on top.  Instead
16635                                    // give them the best state after that.
16636                                    clientProcState =
16637                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16638                                }
16639                            }
16640                        } else {
16641                            if (clientProcState <
16642                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16643                                clientProcState =
16644                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16645                            }
16646                        }
16647                        if (procState > clientProcState) {
16648                            procState = clientProcState;
16649                        }
16650                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16651                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16652                            app.pendingUiClean = true;
16653                        }
16654                        if (adjType != null) {
16655                            app.adjType = adjType;
16656                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16657                                    .REASON_SERVICE_IN_USE;
16658                            app.adjSource = cr.binding.client;
16659                            app.adjSourceProcState = clientProcState;
16660                            app.adjTarget = s.name;
16661                        }
16662                    }
16663                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16664                        app.treatLikeActivity = true;
16665                    }
16666                    final ActivityRecord a = cr.activity;
16667                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16668                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16669                                (a.visible || a.state == ActivityState.RESUMED
16670                                 || a.state == ActivityState.PAUSING)) {
16671                            adj = ProcessList.FOREGROUND_APP_ADJ;
16672                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16673                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16674                            }
16675                            app.cached = false;
16676                            app.adjType = "service";
16677                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16678                                    .REASON_SERVICE_IN_USE;
16679                            app.adjSource = a;
16680                            app.adjSourceProcState = procState;
16681                            app.adjTarget = s.name;
16682                        }
16683                    }
16684                }
16685            }
16686        }
16687
16688        for (int provi = app.pubProviders.size()-1;
16689                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16690                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16691                        || procState > ActivityManager.PROCESS_STATE_TOP);
16692                provi--) {
16693            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16694            for (int i = cpr.connections.size()-1;
16695                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16696                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16697                            || procState > ActivityManager.PROCESS_STATE_TOP);
16698                    i--) {
16699                ContentProviderConnection conn = cpr.connections.get(i);
16700                ProcessRecord client = conn.client;
16701                if (client == app) {
16702                    // Being our own client is not interesting.
16703                    continue;
16704                }
16705                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16706                int clientProcState = client.curProcState;
16707                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16708                    // If the other app is cached for any reason, for purposes here
16709                    // we are going to consider it empty.
16710                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16711                }
16712                if (adj > clientAdj) {
16713                    if (app.hasShownUi && app != mHomeProcess
16714                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16715                        app.adjType = "cch-ui-provider";
16716                    } else {
16717                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16718                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16719                        app.adjType = "provider";
16720                    }
16721                    app.cached &= client.cached;
16722                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16723                            .REASON_PROVIDER_IN_USE;
16724                    app.adjSource = client;
16725                    app.adjSourceProcState = clientProcState;
16726                    app.adjTarget = cpr.name;
16727                }
16728                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16729                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16730                        // Special handling of clients who are in the top state.
16731                        // We *may* want to consider this process to be in the
16732                        // top state as well, but only if there is not another
16733                        // reason for it to be running.  Being on the top is a
16734                        // special state, meaning you are specifically running
16735                        // for the current top app.  If the process is already
16736                        // running in the background for some other reason, it
16737                        // is more important to continue considering it to be
16738                        // in the background state.
16739                        mayBeTop = true;
16740                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16741                    } else {
16742                        // Special handling for above-top states (persistent
16743                        // processes).  These should not bring the current process
16744                        // into the top state, since they are not on top.  Instead
16745                        // give them the best state after that.
16746                        clientProcState =
16747                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16748                    }
16749                }
16750                if (procState > clientProcState) {
16751                    procState = clientProcState;
16752                }
16753                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16754                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16755                }
16756            }
16757            // If the provider has external (non-framework) process
16758            // dependencies, ensure that its adjustment is at least
16759            // FOREGROUND_APP_ADJ.
16760            if (cpr.hasExternalProcessHandles()) {
16761                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16762                    adj = ProcessList.FOREGROUND_APP_ADJ;
16763                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16764                    app.cached = false;
16765                    app.adjType = "provider";
16766                    app.adjTarget = cpr.name;
16767                }
16768                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16769                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16770                }
16771            }
16772        }
16773
16774        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16775            // A client of one of our services or providers is in the top state.  We
16776            // *may* want to be in the top state, but not if we are already running in
16777            // the background for some other reason.  For the decision here, we are going
16778            // to pick out a few specific states that we want to remain in when a client
16779            // is top (states that tend to be longer-term) and otherwise allow it to go
16780            // to the top state.
16781            switch (procState) {
16782                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16783                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16784                case ActivityManager.PROCESS_STATE_SERVICE:
16785                    // These all are longer-term states, so pull them up to the top
16786                    // of the background states, but not all the way to the top state.
16787                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16788                    break;
16789                default:
16790                    // Otherwise, top is a better choice, so take it.
16791                    procState = ActivityManager.PROCESS_STATE_TOP;
16792                    break;
16793            }
16794        }
16795
16796        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16797            if (app.hasClientActivities) {
16798                // This is a cached process, but with client activities.  Mark it so.
16799                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16800                app.adjType = "cch-client-act";
16801            } else if (app.treatLikeActivity) {
16802                // This is a cached process, but somebody wants us to treat it like it has
16803                // an activity, okay!
16804                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16805                app.adjType = "cch-as-act";
16806            }
16807        }
16808
16809        if (adj == ProcessList.SERVICE_ADJ) {
16810            if (doingAll) {
16811                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16812                mNewNumServiceProcs++;
16813                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16814                if (!app.serviceb) {
16815                    // This service isn't far enough down on the LRU list to
16816                    // normally be a B service, but if we are low on RAM and it
16817                    // is large we want to force it down since we would prefer to
16818                    // keep launcher over it.
16819                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16820                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16821                        app.serviceHighRam = true;
16822                        app.serviceb = true;
16823                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16824                    } else {
16825                        mNewNumAServiceProcs++;
16826                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16827                    }
16828                } else {
16829                    app.serviceHighRam = false;
16830                }
16831            }
16832            if (app.serviceb) {
16833                adj = ProcessList.SERVICE_B_ADJ;
16834            }
16835        }
16836
16837        app.curRawAdj = adj;
16838
16839        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16840        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16841        if (adj > app.maxAdj) {
16842            adj = app.maxAdj;
16843            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16844                schedGroup = Process.THREAD_GROUP_DEFAULT;
16845            }
16846        }
16847
16848        // Do final modification to adj.  Everything we do between here and applying
16849        // the final setAdj must be done in this function, because we will also use
16850        // it when computing the final cached adj later.  Note that we don't need to
16851        // worry about this for max adj above, since max adj will always be used to
16852        // keep it out of the cached vaues.
16853        app.curAdj = app.modifyRawOomAdj(adj);
16854        app.curSchedGroup = schedGroup;
16855        app.curProcState = procState;
16856        app.foregroundActivities = foregroundActivities;
16857
16858        return app.curRawAdj;
16859    }
16860
16861    /**
16862     * Schedule PSS collection of a process.
16863     */
16864    void requestPssLocked(ProcessRecord proc, int procState) {
16865        if (mPendingPssProcesses.contains(proc)) {
16866            return;
16867        }
16868        if (mPendingPssProcesses.size() == 0) {
16869            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16870        }
16871        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16872        proc.pssProcState = procState;
16873        mPendingPssProcesses.add(proc);
16874    }
16875
16876    /**
16877     * Schedule PSS collection of all processes.
16878     */
16879    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16880        if (!always) {
16881            if (now < (mLastFullPssTime +
16882                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16883                return;
16884            }
16885        }
16886        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16887        mLastFullPssTime = now;
16888        mFullPssPending = true;
16889        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16890        mPendingPssProcesses.clear();
16891        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16892            ProcessRecord app = mLruProcesses.get(i);
16893            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16894                app.pssProcState = app.setProcState;
16895                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16896                        isSleeping(), now);
16897                mPendingPssProcesses.add(app);
16898            }
16899        }
16900        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16901    }
16902
16903    /**
16904     * Ask a given process to GC right now.
16905     */
16906    final void performAppGcLocked(ProcessRecord app) {
16907        try {
16908            app.lastRequestedGc = SystemClock.uptimeMillis();
16909            if (app.thread != null) {
16910                if (app.reportLowMemory) {
16911                    app.reportLowMemory = false;
16912                    app.thread.scheduleLowMemory();
16913                } else {
16914                    app.thread.processInBackground();
16915                }
16916            }
16917        } catch (Exception e) {
16918            // whatever.
16919        }
16920    }
16921
16922    /**
16923     * Returns true if things are idle enough to perform GCs.
16924     */
16925    private final boolean canGcNowLocked() {
16926        boolean processingBroadcasts = false;
16927        for (BroadcastQueue q : mBroadcastQueues) {
16928            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16929                processingBroadcasts = true;
16930            }
16931        }
16932        return !processingBroadcasts
16933                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16934    }
16935
16936    /**
16937     * Perform GCs on all processes that are waiting for it, but only
16938     * if things are idle.
16939     */
16940    final void performAppGcsLocked() {
16941        final int N = mProcessesToGc.size();
16942        if (N <= 0) {
16943            return;
16944        }
16945        if (canGcNowLocked()) {
16946            while (mProcessesToGc.size() > 0) {
16947                ProcessRecord proc = mProcessesToGc.remove(0);
16948                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16949                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16950                            <= SystemClock.uptimeMillis()) {
16951                        // To avoid spamming the system, we will GC processes one
16952                        // at a time, waiting a few seconds between each.
16953                        performAppGcLocked(proc);
16954                        scheduleAppGcsLocked();
16955                        return;
16956                    } else {
16957                        // It hasn't been long enough since we last GCed this
16958                        // process...  put it in the list to wait for its time.
16959                        addProcessToGcListLocked(proc);
16960                        break;
16961                    }
16962                }
16963            }
16964
16965            scheduleAppGcsLocked();
16966        }
16967    }
16968
16969    /**
16970     * If all looks good, perform GCs on all processes waiting for them.
16971     */
16972    final void performAppGcsIfAppropriateLocked() {
16973        if (canGcNowLocked()) {
16974            performAppGcsLocked();
16975            return;
16976        }
16977        // Still not idle, wait some more.
16978        scheduleAppGcsLocked();
16979    }
16980
16981    /**
16982     * Schedule the execution of all pending app GCs.
16983     */
16984    final void scheduleAppGcsLocked() {
16985        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16986
16987        if (mProcessesToGc.size() > 0) {
16988            // Schedule a GC for the time to the next process.
16989            ProcessRecord proc = mProcessesToGc.get(0);
16990            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16991
16992            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16993            long now = SystemClock.uptimeMillis();
16994            if (when < (now+GC_TIMEOUT)) {
16995                when = now + GC_TIMEOUT;
16996            }
16997            mHandler.sendMessageAtTime(msg, when);
16998        }
16999    }
17000
17001    /**
17002     * Add a process to the array of processes waiting to be GCed.  Keeps the
17003     * list in sorted order by the last GC time.  The process can't already be
17004     * on the list.
17005     */
17006    final void addProcessToGcListLocked(ProcessRecord proc) {
17007        boolean added = false;
17008        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17009            if (mProcessesToGc.get(i).lastRequestedGc <
17010                    proc.lastRequestedGc) {
17011                added = true;
17012                mProcessesToGc.add(i+1, proc);
17013                break;
17014            }
17015        }
17016        if (!added) {
17017            mProcessesToGc.add(0, proc);
17018        }
17019    }
17020
17021    /**
17022     * Set up to ask a process to GC itself.  This will either do it
17023     * immediately, or put it on the list of processes to gc the next
17024     * time things are idle.
17025     */
17026    final void scheduleAppGcLocked(ProcessRecord app) {
17027        long now = SystemClock.uptimeMillis();
17028        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17029            return;
17030        }
17031        if (!mProcessesToGc.contains(app)) {
17032            addProcessToGcListLocked(app);
17033            scheduleAppGcsLocked();
17034        }
17035    }
17036
17037    final void checkExcessivePowerUsageLocked(boolean doKills) {
17038        updateCpuStatsNow();
17039
17040        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17041        boolean doWakeKills = doKills;
17042        boolean doCpuKills = doKills;
17043        if (mLastPowerCheckRealtime == 0) {
17044            doWakeKills = false;
17045        }
17046        if (mLastPowerCheckUptime == 0) {
17047            doCpuKills = false;
17048        }
17049        if (stats.isScreenOn()) {
17050            doWakeKills = false;
17051        }
17052        final long curRealtime = SystemClock.elapsedRealtime();
17053        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17054        final long curUptime = SystemClock.uptimeMillis();
17055        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17056        mLastPowerCheckRealtime = curRealtime;
17057        mLastPowerCheckUptime = curUptime;
17058        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17059            doWakeKills = false;
17060        }
17061        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17062            doCpuKills = false;
17063        }
17064        int i = mLruProcesses.size();
17065        while (i > 0) {
17066            i--;
17067            ProcessRecord app = mLruProcesses.get(i);
17068            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17069                long wtime;
17070                synchronized (stats) {
17071                    wtime = stats.getProcessWakeTime(app.info.uid,
17072                            app.pid, curRealtime);
17073                }
17074                long wtimeUsed = wtime - app.lastWakeTime;
17075                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17076                if (DEBUG_POWER) {
17077                    StringBuilder sb = new StringBuilder(128);
17078                    sb.append("Wake for ");
17079                    app.toShortString(sb);
17080                    sb.append(": over ");
17081                    TimeUtils.formatDuration(realtimeSince, sb);
17082                    sb.append(" used ");
17083                    TimeUtils.formatDuration(wtimeUsed, sb);
17084                    sb.append(" (");
17085                    sb.append((wtimeUsed*100)/realtimeSince);
17086                    sb.append("%)");
17087                    Slog.i(TAG, sb.toString());
17088                    sb.setLength(0);
17089                    sb.append("CPU for ");
17090                    app.toShortString(sb);
17091                    sb.append(": over ");
17092                    TimeUtils.formatDuration(uptimeSince, sb);
17093                    sb.append(" used ");
17094                    TimeUtils.formatDuration(cputimeUsed, sb);
17095                    sb.append(" (");
17096                    sb.append((cputimeUsed*100)/uptimeSince);
17097                    sb.append("%)");
17098                    Slog.i(TAG, sb.toString());
17099                }
17100                // If a process has held a wake lock for more
17101                // than 50% of the time during this period,
17102                // that sounds bad.  Kill!
17103                if (doWakeKills && realtimeSince > 0
17104                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17105                    synchronized (stats) {
17106                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17107                                realtimeSince, wtimeUsed);
17108                    }
17109                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17110                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17111                } else if (doCpuKills && uptimeSince > 0
17112                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17113                    synchronized (stats) {
17114                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17115                                uptimeSince, cputimeUsed);
17116                    }
17117                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17118                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17119                } else {
17120                    app.lastWakeTime = wtime;
17121                    app.lastCpuTime = app.curCpuTime;
17122                }
17123            }
17124        }
17125    }
17126
17127    private final boolean applyOomAdjLocked(ProcessRecord app,
17128            ProcessRecord TOP_APP, boolean doingAll, long now) {
17129        boolean success = true;
17130
17131        if (app.curRawAdj != app.setRawAdj) {
17132            app.setRawAdj = app.curRawAdj;
17133        }
17134
17135        int changes = 0;
17136
17137        if (app.curAdj != app.setAdj) {
17138            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17139            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17140                TAG, "Set " + app.pid + " " + app.processName +
17141                " adj " + app.curAdj + ": " + app.adjType);
17142            app.setAdj = app.curAdj;
17143        }
17144
17145        if (app.setSchedGroup != app.curSchedGroup) {
17146            app.setSchedGroup = app.curSchedGroup;
17147            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17148                    "Setting process group of " + app.processName
17149                    + " to " + app.curSchedGroup);
17150            if (app.waitingToKill != null &&
17151                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17152                app.kill(app.waitingToKill, true);
17153                success = false;
17154            } else {
17155                if (true) {
17156                    long oldId = Binder.clearCallingIdentity();
17157                    try {
17158                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17159                    } catch (Exception e) {
17160                        Slog.w(TAG, "Failed setting process group of " + app.pid
17161                                + " to " + app.curSchedGroup);
17162                        e.printStackTrace();
17163                    } finally {
17164                        Binder.restoreCallingIdentity(oldId);
17165                    }
17166                } else {
17167                    if (app.thread != null) {
17168                        try {
17169                            app.thread.setSchedulingGroup(app.curSchedGroup);
17170                        } catch (RemoteException e) {
17171                        }
17172                    }
17173                }
17174                Process.setSwappiness(app.pid,
17175                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17176            }
17177        }
17178        if (app.repForegroundActivities != app.foregroundActivities) {
17179            app.repForegroundActivities = app.foregroundActivities;
17180            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17181        }
17182        if (app.repProcState != app.curProcState) {
17183            app.repProcState = app.curProcState;
17184            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17185            if (app.thread != null) {
17186                try {
17187                    if (false) {
17188                        //RuntimeException h = new RuntimeException("here");
17189                        Slog.i(TAG, "Sending new process state " + app.repProcState
17190                                + " to " + app /*, h*/);
17191                    }
17192                    app.thread.setProcessState(app.repProcState);
17193                } catch (RemoteException e) {
17194                }
17195            }
17196        }
17197        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17198                app.setProcState)) {
17199            app.lastStateTime = now;
17200            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17201                    isSleeping(), now);
17202            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17203                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17204                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17205                    + (app.nextPssTime-now) + ": " + app);
17206        } else {
17207            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17208                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17209                requestPssLocked(app, app.setProcState);
17210                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17211                        isSleeping(), now);
17212            } else if (false && DEBUG_PSS) {
17213                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17214            }
17215        }
17216        if (app.setProcState != app.curProcState) {
17217            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17218                    "Proc state change of " + app.processName
17219                    + " to " + app.curProcState);
17220            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17221            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17222            if (setImportant && !curImportant) {
17223                // This app is no longer something we consider important enough to allow to
17224                // use arbitrary amounts of battery power.  Note
17225                // its current wake lock time to later know to kill it if
17226                // it is not behaving well.
17227                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17228                synchronized (stats) {
17229                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17230                            app.pid, SystemClock.elapsedRealtime());
17231                }
17232                app.lastCpuTime = app.curCpuTime;
17233
17234            }
17235            app.setProcState = app.curProcState;
17236            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17237                app.notCachedSinceIdle = false;
17238            }
17239            if (!doingAll) {
17240                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17241            } else {
17242                app.procStateChanged = true;
17243            }
17244        }
17245
17246        if (changes != 0) {
17247            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17248            int i = mPendingProcessChanges.size()-1;
17249            ProcessChangeItem item = null;
17250            while (i >= 0) {
17251                item = mPendingProcessChanges.get(i);
17252                if (item.pid == app.pid) {
17253                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17254                    break;
17255                }
17256                i--;
17257            }
17258            if (i < 0) {
17259                // No existing item in pending changes; need a new one.
17260                final int NA = mAvailProcessChanges.size();
17261                if (NA > 0) {
17262                    item = mAvailProcessChanges.remove(NA-1);
17263                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17264                } else {
17265                    item = new ProcessChangeItem();
17266                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17267                }
17268                item.changes = 0;
17269                item.pid = app.pid;
17270                item.uid = app.info.uid;
17271                if (mPendingProcessChanges.size() == 0) {
17272                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17273                            "*** Enqueueing dispatch processes changed!");
17274                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17275                }
17276                mPendingProcessChanges.add(item);
17277            }
17278            item.changes |= changes;
17279            item.processState = app.repProcState;
17280            item.foregroundActivities = app.repForegroundActivities;
17281            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17282                    + Integer.toHexString(System.identityHashCode(item))
17283                    + " " + app.toShortString() + ": changes=" + item.changes
17284                    + " procState=" + item.processState
17285                    + " foreground=" + item.foregroundActivities
17286                    + " type=" + app.adjType + " source=" + app.adjSource
17287                    + " target=" + app.adjTarget);
17288        }
17289
17290        return success;
17291    }
17292
17293    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17294        if (proc.thread != null) {
17295            if (proc.baseProcessTracker != null) {
17296                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17297            }
17298            if (proc.repProcState >= 0) {
17299                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17300                        proc.repProcState);
17301            }
17302        }
17303    }
17304
17305    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17306            ProcessRecord TOP_APP, boolean doingAll, long now) {
17307        if (app.thread == null) {
17308            return false;
17309        }
17310
17311        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17312
17313        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17314    }
17315
17316    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17317            boolean oomAdj) {
17318        if (isForeground != proc.foregroundServices) {
17319            proc.foregroundServices = isForeground;
17320            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17321                    proc.info.uid);
17322            if (isForeground) {
17323                if (curProcs == null) {
17324                    curProcs = new ArrayList<ProcessRecord>();
17325                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17326                }
17327                if (!curProcs.contains(proc)) {
17328                    curProcs.add(proc);
17329                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17330                            proc.info.packageName, proc.info.uid);
17331                }
17332            } else {
17333                if (curProcs != null) {
17334                    if (curProcs.remove(proc)) {
17335                        mBatteryStatsService.noteEvent(
17336                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17337                                proc.info.packageName, proc.info.uid);
17338                        if (curProcs.size() <= 0) {
17339                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17340                        }
17341                    }
17342                }
17343            }
17344            if (oomAdj) {
17345                updateOomAdjLocked();
17346            }
17347        }
17348    }
17349
17350    private final ActivityRecord resumedAppLocked() {
17351        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17352        String pkg;
17353        int uid;
17354        if (act != null) {
17355            pkg = act.packageName;
17356            uid = act.info.applicationInfo.uid;
17357        } else {
17358            pkg = null;
17359            uid = -1;
17360        }
17361        // Has the UID or resumed package name changed?
17362        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17363                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17364            if (mCurResumedPackage != null) {
17365                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17366                        mCurResumedPackage, mCurResumedUid);
17367            }
17368            mCurResumedPackage = pkg;
17369            mCurResumedUid = uid;
17370            if (mCurResumedPackage != null) {
17371                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17372                        mCurResumedPackage, mCurResumedUid);
17373            }
17374        }
17375        return act;
17376    }
17377
17378    final boolean updateOomAdjLocked(ProcessRecord app) {
17379        final ActivityRecord TOP_ACT = resumedAppLocked();
17380        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17381        final boolean wasCached = app.cached;
17382
17383        mAdjSeq++;
17384
17385        // This is the desired cached adjusment we want to tell it to use.
17386        // If our app is currently cached, we know it, and that is it.  Otherwise,
17387        // we don't know it yet, and it needs to now be cached we will then
17388        // need to do a complete oom adj.
17389        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17390                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17391        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17392                SystemClock.uptimeMillis());
17393        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17394            // Changed to/from cached state, so apps after it in the LRU
17395            // list may also be changed.
17396            updateOomAdjLocked();
17397        }
17398        return success;
17399    }
17400
17401    final void updateOomAdjLocked() {
17402        final ActivityRecord TOP_ACT = resumedAppLocked();
17403        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17404        final long now = SystemClock.uptimeMillis();
17405        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17406        final int N = mLruProcesses.size();
17407
17408        if (false) {
17409            RuntimeException e = new RuntimeException();
17410            e.fillInStackTrace();
17411            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17412        }
17413
17414        mAdjSeq++;
17415        mNewNumServiceProcs = 0;
17416        mNewNumAServiceProcs = 0;
17417
17418        final int emptyProcessLimit;
17419        final int cachedProcessLimit;
17420        if (mProcessLimit <= 0) {
17421            emptyProcessLimit = cachedProcessLimit = 0;
17422        } else if (mProcessLimit == 1) {
17423            emptyProcessLimit = 1;
17424            cachedProcessLimit = 0;
17425        } else {
17426            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17427            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17428        }
17429
17430        // Let's determine how many processes we have running vs.
17431        // how many slots we have for background processes; we may want
17432        // to put multiple processes in a slot of there are enough of
17433        // them.
17434        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17435                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17436        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17437        if (numEmptyProcs > cachedProcessLimit) {
17438            // If there are more empty processes than our limit on cached
17439            // processes, then use the cached process limit for the factor.
17440            // This ensures that the really old empty processes get pushed
17441            // down to the bottom, so if we are running low on memory we will
17442            // have a better chance at keeping around more cached processes
17443            // instead of a gazillion empty processes.
17444            numEmptyProcs = cachedProcessLimit;
17445        }
17446        int emptyFactor = numEmptyProcs/numSlots;
17447        if (emptyFactor < 1) emptyFactor = 1;
17448        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17449        if (cachedFactor < 1) cachedFactor = 1;
17450        int stepCached = 0;
17451        int stepEmpty = 0;
17452        int numCached = 0;
17453        int numEmpty = 0;
17454        int numTrimming = 0;
17455
17456        mNumNonCachedProcs = 0;
17457        mNumCachedHiddenProcs = 0;
17458
17459        // First update the OOM adjustment for each of the
17460        // application processes based on their current state.
17461        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17462        int nextCachedAdj = curCachedAdj+1;
17463        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17464        int nextEmptyAdj = curEmptyAdj+2;
17465        for (int i=N-1; i>=0; i--) {
17466            ProcessRecord app = mLruProcesses.get(i);
17467            if (!app.killedByAm && app.thread != null) {
17468                app.procStateChanged = false;
17469                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17470
17471                // If we haven't yet assigned the final cached adj
17472                // to the process, do that now.
17473                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17474                    switch (app.curProcState) {
17475                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17476                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17477                            // This process is a cached process holding activities...
17478                            // assign it the next cached value for that type, and then
17479                            // step that cached level.
17480                            app.curRawAdj = curCachedAdj;
17481                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17482                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17483                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17484                                    + ")");
17485                            if (curCachedAdj != nextCachedAdj) {
17486                                stepCached++;
17487                                if (stepCached >= cachedFactor) {
17488                                    stepCached = 0;
17489                                    curCachedAdj = nextCachedAdj;
17490                                    nextCachedAdj += 2;
17491                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17492                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17493                                    }
17494                                }
17495                            }
17496                            break;
17497                        default:
17498                            // For everything else, assign next empty cached process
17499                            // level and bump that up.  Note that this means that
17500                            // long-running services that have dropped down to the
17501                            // cached level will be treated as empty (since their process
17502                            // state is still as a service), which is what we want.
17503                            app.curRawAdj = curEmptyAdj;
17504                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17505                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17506                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17507                                    + ")");
17508                            if (curEmptyAdj != nextEmptyAdj) {
17509                                stepEmpty++;
17510                                if (stepEmpty >= emptyFactor) {
17511                                    stepEmpty = 0;
17512                                    curEmptyAdj = nextEmptyAdj;
17513                                    nextEmptyAdj += 2;
17514                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17515                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17516                                    }
17517                                }
17518                            }
17519                            break;
17520                    }
17521                }
17522
17523                applyOomAdjLocked(app, TOP_APP, true, now);
17524
17525                // Count the number of process types.
17526                switch (app.curProcState) {
17527                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17528                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17529                        mNumCachedHiddenProcs++;
17530                        numCached++;
17531                        if (numCached > cachedProcessLimit) {
17532                            app.kill("cached #" + numCached, true);
17533                        }
17534                        break;
17535                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17536                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17537                                && app.lastActivityTime < oldTime) {
17538                            app.kill("empty for "
17539                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17540                                    / 1000) + "s", true);
17541                        } else {
17542                            numEmpty++;
17543                            if (numEmpty > emptyProcessLimit) {
17544                                app.kill("empty #" + numEmpty, true);
17545                            }
17546                        }
17547                        break;
17548                    default:
17549                        mNumNonCachedProcs++;
17550                        break;
17551                }
17552
17553                if (app.isolated && app.services.size() <= 0) {
17554                    // If this is an isolated process, and there are no
17555                    // services running in it, then the process is no longer
17556                    // needed.  We agressively kill these because we can by
17557                    // definition not re-use the same process again, and it is
17558                    // good to avoid having whatever code was running in them
17559                    // left sitting around after no longer needed.
17560                    app.kill("isolated not needed", true);
17561                }
17562
17563                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17564                        && !app.killedByAm) {
17565                    numTrimming++;
17566                }
17567            }
17568        }
17569
17570        mNumServiceProcs = mNewNumServiceProcs;
17571
17572        // Now determine the memory trimming level of background processes.
17573        // Unfortunately we need to start at the back of the list to do this
17574        // properly.  We only do this if the number of background apps we
17575        // are managing to keep around is less than half the maximum we desire;
17576        // if we are keeping a good number around, we'll let them use whatever
17577        // memory they want.
17578        final int numCachedAndEmpty = numCached + numEmpty;
17579        int memFactor;
17580        if (numCached <= ProcessList.TRIM_CACHED_APPS
17581                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17582            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17583                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17584            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17585                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17586            } else {
17587                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17588            }
17589        } else {
17590            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17591        }
17592        // We always allow the memory level to go up (better).  We only allow it to go
17593        // down if we are in a state where that is allowed, *and* the total number of processes
17594        // has gone down since last time.
17595        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17596                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17597                + " last=" + mLastNumProcesses);
17598        if (memFactor > mLastMemoryLevel) {
17599            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17600                memFactor = mLastMemoryLevel;
17601                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17602            }
17603        }
17604        mLastMemoryLevel = memFactor;
17605        mLastNumProcesses = mLruProcesses.size();
17606        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17607        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17608        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17609            if (mLowRamStartTime == 0) {
17610                mLowRamStartTime = now;
17611            }
17612            int step = 0;
17613            int fgTrimLevel;
17614            switch (memFactor) {
17615                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17616                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17617                    break;
17618                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17619                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17620                    break;
17621                default:
17622                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17623                    break;
17624            }
17625            int factor = numTrimming/3;
17626            int minFactor = 2;
17627            if (mHomeProcess != null) minFactor++;
17628            if (mPreviousProcess != null) minFactor++;
17629            if (factor < minFactor) factor = minFactor;
17630            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17631            for (int i=N-1; i>=0; i--) {
17632                ProcessRecord app = mLruProcesses.get(i);
17633                if (allChanged || app.procStateChanged) {
17634                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17635                    app.procStateChanged = false;
17636                }
17637                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17638                        && !app.killedByAm) {
17639                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17640                        try {
17641                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17642                                    "Trimming memory of " + app.processName
17643                                    + " to " + curLevel);
17644                            app.thread.scheduleTrimMemory(curLevel);
17645                        } catch (RemoteException e) {
17646                        }
17647                        if (false) {
17648                            // For now we won't do this; our memory trimming seems
17649                            // to be good enough at this point that destroying
17650                            // activities causes more harm than good.
17651                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17652                                    && app != mHomeProcess && app != mPreviousProcess) {
17653                                // Need to do this on its own message because the stack may not
17654                                // be in a consistent state at this point.
17655                                // For these apps we will also finish their activities
17656                                // to help them free memory.
17657                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17658                            }
17659                        }
17660                    }
17661                    app.trimMemoryLevel = curLevel;
17662                    step++;
17663                    if (step >= factor) {
17664                        step = 0;
17665                        switch (curLevel) {
17666                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17667                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17668                                break;
17669                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17670                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17671                                break;
17672                        }
17673                    }
17674                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17675                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17676                            && app.thread != null) {
17677                        try {
17678                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17679                                    "Trimming memory of heavy-weight " + app.processName
17680                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17681                            app.thread.scheduleTrimMemory(
17682                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17683                        } catch (RemoteException e) {
17684                        }
17685                    }
17686                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17687                } else {
17688                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17689                            || app.systemNoUi) && app.pendingUiClean) {
17690                        // If this application is now in the background and it
17691                        // had done UI, then give it the special trim level to
17692                        // have it free UI resources.
17693                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17694                        if (app.trimMemoryLevel < level && app.thread != null) {
17695                            try {
17696                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17697                                        "Trimming memory of bg-ui " + app.processName
17698                                        + " to " + level);
17699                                app.thread.scheduleTrimMemory(level);
17700                            } catch (RemoteException e) {
17701                            }
17702                        }
17703                        app.pendingUiClean = false;
17704                    }
17705                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17706                        try {
17707                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17708                                    "Trimming memory of fg " + app.processName
17709                                    + " to " + fgTrimLevel);
17710                            app.thread.scheduleTrimMemory(fgTrimLevel);
17711                        } catch (RemoteException e) {
17712                        }
17713                    }
17714                    app.trimMemoryLevel = fgTrimLevel;
17715                }
17716            }
17717        } else {
17718            if (mLowRamStartTime != 0) {
17719                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17720                mLowRamStartTime = 0;
17721            }
17722            for (int i=N-1; i>=0; i--) {
17723                ProcessRecord app = mLruProcesses.get(i);
17724                if (allChanged || app.procStateChanged) {
17725                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17726                    app.procStateChanged = false;
17727                }
17728                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17729                        || app.systemNoUi) && app.pendingUiClean) {
17730                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17731                            && app.thread != null) {
17732                        try {
17733                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17734                                    "Trimming memory of ui hidden " + app.processName
17735                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17736                            app.thread.scheduleTrimMemory(
17737                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17738                        } catch (RemoteException e) {
17739                        }
17740                    }
17741                    app.pendingUiClean = false;
17742                }
17743                app.trimMemoryLevel = 0;
17744            }
17745        }
17746
17747        if (mAlwaysFinishActivities) {
17748            // Need to do this on its own message because the stack may not
17749            // be in a consistent state at this point.
17750            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17751        }
17752
17753        if (allChanged) {
17754            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17755        }
17756
17757        if (mProcessStats.shouldWriteNowLocked(now)) {
17758            mHandler.post(new Runnable() {
17759                @Override public void run() {
17760                    synchronized (ActivityManagerService.this) {
17761                        mProcessStats.writeStateAsyncLocked();
17762                    }
17763                }
17764            });
17765        }
17766
17767        if (DEBUG_OOM_ADJ) {
17768            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17769        }
17770    }
17771
17772    final void trimApplications() {
17773        synchronized (this) {
17774            int i;
17775
17776            // First remove any unused application processes whose package
17777            // has been removed.
17778            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17779                final ProcessRecord app = mRemovedProcesses.get(i);
17780                if (app.activities.size() == 0
17781                        && app.curReceiver == null && app.services.size() == 0) {
17782                    Slog.i(
17783                        TAG, "Exiting empty application process "
17784                        + app.processName + " ("
17785                        + (app.thread != null ? app.thread.asBinder() : null)
17786                        + ")\n");
17787                    if (app.pid > 0 && app.pid != MY_PID) {
17788                        app.kill("empty", false);
17789                    } else {
17790                        try {
17791                            app.thread.scheduleExit();
17792                        } catch (Exception e) {
17793                            // Ignore exceptions.
17794                        }
17795                    }
17796                    cleanUpApplicationRecordLocked(app, false, true, -1);
17797                    mRemovedProcesses.remove(i);
17798
17799                    if (app.persistent) {
17800                        addAppLocked(app.info, false, null /* ABI override */);
17801                    }
17802                }
17803            }
17804
17805            // Now update the oom adj for all processes.
17806            updateOomAdjLocked();
17807        }
17808    }
17809
17810    /** This method sends the specified signal to each of the persistent apps */
17811    public void signalPersistentProcesses(int sig) throws RemoteException {
17812        if (sig != Process.SIGNAL_USR1) {
17813            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17814        }
17815
17816        synchronized (this) {
17817            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17818                    != PackageManager.PERMISSION_GRANTED) {
17819                throw new SecurityException("Requires permission "
17820                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17821            }
17822
17823            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17824                ProcessRecord r = mLruProcesses.get(i);
17825                if (r.thread != null && r.persistent) {
17826                    Process.sendSignal(r.pid, sig);
17827                }
17828            }
17829        }
17830    }
17831
17832    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17833        if (proc == null || proc == mProfileProc) {
17834            proc = mProfileProc;
17835            profileType = mProfileType;
17836            clearProfilerLocked();
17837        }
17838        if (proc == null) {
17839            return;
17840        }
17841        try {
17842            proc.thread.profilerControl(false, null, profileType);
17843        } catch (RemoteException e) {
17844            throw new IllegalStateException("Process disappeared");
17845        }
17846    }
17847
17848    private void clearProfilerLocked() {
17849        if (mProfileFd != null) {
17850            try {
17851                mProfileFd.close();
17852            } catch (IOException e) {
17853            }
17854        }
17855        mProfileApp = null;
17856        mProfileProc = null;
17857        mProfileFile = null;
17858        mProfileType = 0;
17859        mAutoStopProfiler = false;
17860        mSamplingInterval = 0;
17861    }
17862
17863    public boolean profileControl(String process, int userId, boolean start,
17864            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17865
17866        try {
17867            synchronized (this) {
17868                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17869                // its own permission.
17870                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17871                        != PackageManager.PERMISSION_GRANTED) {
17872                    throw new SecurityException("Requires permission "
17873                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17874                }
17875
17876                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17877                    throw new IllegalArgumentException("null profile info or fd");
17878                }
17879
17880                ProcessRecord proc = null;
17881                if (process != null) {
17882                    proc = findProcessLocked(process, userId, "profileControl");
17883                }
17884
17885                if (start && (proc == null || proc.thread == null)) {
17886                    throw new IllegalArgumentException("Unknown process: " + process);
17887                }
17888
17889                if (start) {
17890                    stopProfilerLocked(null, 0);
17891                    setProfileApp(proc.info, proc.processName, profilerInfo);
17892                    mProfileProc = proc;
17893                    mProfileType = profileType;
17894                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17895                    try {
17896                        fd = fd.dup();
17897                    } catch (IOException e) {
17898                        fd = null;
17899                    }
17900                    profilerInfo.profileFd = fd;
17901                    proc.thread.profilerControl(start, profilerInfo, profileType);
17902                    fd = null;
17903                    mProfileFd = null;
17904                } else {
17905                    stopProfilerLocked(proc, profileType);
17906                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17907                        try {
17908                            profilerInfo.profileFd.close();
17909                        } catch (IOException e) {
17910                        }
17911                    }
17912                }
17913
17914                return true;
17915            }
17916        } catch (RemoteException e) {
17917            throw new IllegalStateException("Process disappeared");
17918        } finally {
17919            if (profilerInfo != null && profilerInfo.profileFd != null) {
17920                try {
17921                    profilerInfo.profileFd.close();
17922                } catch (IOException e) {
17923                }
17924            }
17925        }
17926    }
17927
17928    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17929        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17930                userId, true, ALLOW_FULL_ONLY, callName, null);
17931        ProcessRecord proc = null;
17932        try {
17933            int pid = Integer.parseInt(process);
17934            synchronized (mPidsSelfLocked) {
17935                proc = mPidsSelfLocked.get(pid);
17936            }
17937        } catch (NumberFormatException e) {
17938        }
17939
17940        if (proc == null) {
17941            ArrayMap<String, SparseArray<ProcessRecord>> all
17942                    = mProcessNames.getMap();
17943            SparseArray<ProcessRecord> procs = all.get(process);
17944            if (procs != null && procs.size() > 0) {
17945                proc = procs.valueAt(0);
17946                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17947                    for (int i=1; i<procs.size(); i++) {
17948                        ProcessRecord thisProc = procs.valueAt(i);
17949                        if (thisProc.userId == userId) {
17950                            proc = thisProc;
17951                            break;
17952                        }
17953                    }
17954                }
17955            }
17956        }
17957
17958        return proc;
17959    }
17960
17961    public boolean dumpHeap(String process, int userId, boolean managed,
17962            String path, ParcelFileDescriptor fd) throws RemoteException {
17963
17964        try {
17965            synchronized (this) {
17966                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17967                // its own permission (same as profileControl).
17968                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17969                        != PackageManager.PERMISSION_GRANTED) {
17970                    throw new SecurityException("Requires permission "
17971                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17972                }
17973
17974                if (fd == null) {
17975                    throw new IllegalArgumentException("null fd");
17976                }
17977
17978                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17979                if (proc == null || proc.thread == null) {
17980                    throw new IllegalArgumentException("Unknown process: " + process);
17981                }
17982
17983                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17984                if (!isDebuggable) {
17985                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17986                        throw new SecurityException("Process not debuggable: " + proc);
17987                    }
17988                }
17989
17990                proc.thread.dumpHeap(managed, path, fd);
17991                fd = null;
17992                return true;
17993            }
17994        } catch (RemoteException e) {
17995            throw new IllegalStateException("Process disappeared");
17996        } finally {
17997            if (fd != null) {
17998                try {
17999                    fd.close();
18000                } catch (IOException e) {
18001                }
18002            }
18003        }
18004    }
18005
18006    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18007    public void monitor() {
18008        synchronized (this) { }
18009    }
18010
18011    void onCoreSettingsChange(Bundle settings) {
18012        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18013            ProcessRecord processRecord = mLruProcesses.get(i);
18014            try {
18015                if (processRecord.thread != null) {
18016                    processRecord.thread.setCoreSettings(settings);
18017                }
18018            } catch (RemoteException re) {
18019                /* ignore */
18020            }
18021        }
18022    }
18023
18024    // Multi-user methods
18025
18026    /**
18027     * Start user, if its not already running, but don't bring it to foreground.
18028     */
18029    @Override
18030    public boolean startUserInBackground(final int userId) {
18031        return startUser(userId, /* foreground */ false);
18032    }
18033
18034    /**
18035     * Start user, if its not already running, and bring it to foreground.
18036     */
18037    boolean startUserInForeground(final int userId, Dialog dlg) {
18038        boolean result = startUser(userId, /* foreground */ true);
18039        dlg.dismiss();
18040        return result;
18041    }
18042
18043    /**
18044     * Refreshes the list of users related to the current user when either a
18045     * user switch happens or when a new related user is started in the
18046     * background.
18047     */
18048    private void updateCurrentProfileIdsLocked() {
18049        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18050                mCurrentUserId, false /* enabledOnly */);
18051        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18052        for (int i = 0; i < currentProfileIds.length; i++) {
18053            currentProfileIds[i] = profiles.get(i).id;
18054        }
18055        mCurrentProfileIds = currentProfileIds;
18056
18057        synchronized (mUserProfileGroupIdsSelfLocked) {
18058            mUserProfileGroupIdsSelfLocked.clear();
18059            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18060            for (int i = 0; i < users.size(); i++) {
18061                UserInfo user = users.get(i);
18062                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18063                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18064                }
18065            }
18066        }
18067    }
18068
18069    private Set getProfileIdsLocked(int userId) {
18070        Set userIds = new HashSet<Integer>();
18071        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18072                userId, false /* enabledOnly */);
18073        for (UserInfo user : profiles) {
18074            userIds.add(Integer.valueOf(user.id));
18075        }
18076        return userIds;
18077    }
18078
18079    @Override
18080    public boolean switchUser(final int userId) {
18081        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18082        String userName;
18083        synchronized (this) {
18084            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18085            if (userInfo == null) {
18086                Slog.w(TAG, "No user info for user #" + userId);
18087                return false;
18088            }
18089            if (userInfo.isManagedProfile()) {
18090                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18091                return false;
18092            }
18093            userName = userInfo.name;
18094            mTargetUserId = userId;
18095        }
18096        mHandler.removeMessages(START_USER_SWITCH_MSG);
18097        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18098        return true;
18099    }
18100
18101    private void showUserSwitchDialog(int userId, String userName) {
18102        // The dialog will show and then initiate the user switch by calling startUserInForeground
18103        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18104                true /* above system */);
18105        d.show();
18106    }
18107
18108    private boolean startUser(final int userId, final boolean foreground) {
18109        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18110                != PackageManager.PERMISSION_GRANTED) {
18111            String msg = "Permission Denial: switchUser() from pid="
18112                    + Binder.getCallingPid()
18113                    + ", uid=" + Binder.getCallingUid()
18114                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18115            Slog.w(TAG, msg);
18116            throw new SecurityException(msg);
18117        }
18118
18119        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18120
18121        final long ident = Binder.clearCallingIdentity();
18122        try {
18123            synchronized (this) {
18124                final int oldUserId = mCurrentUserId;
18125                if (oldUserId == userId) {
18126                    return true;
18127                }
18128
18129                mStackSupervisor.setLockTaskModeLocked(null, false);
18130
18131                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18132                if (userInfo == null) {
18133                    Slog.w(TAG, "No user info for user #" + userId);
18134                    return false;
18135                }
18136                if (foreground && userInfo.isManagedProfile()) {
18137                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18138                    return false;
18139                }
18140
18141                if (foreground) {
18142                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18143                            R.anim.screen_user_enter);
18144                }
18145
18146                boolean needStart = false;
18147
18148                // If the user we are switching to is not currently started, then
18149                // we need to start it now.
18150                if (mStartedUsers.get(userId) == null) {
18151                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18152                    updateStartedUserArrayLocked();
18153                    needStart = true;
18154                }
18155
18156                final Integer userIdInt = Integer.valueOf(userId);
18157                mUserLru.remove(userIdInt);
18158                mUserLru.add(userIdInt);
18159
18160                if (foreground) {
18161                    mCurrentUserId = userId;
18162                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18163                    updateCurrentProfileIdsLocked();
18164                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18165                    // Once the internal notion of the active user has switched, we lock the device
18166                    // with the option to show the user switcher on the keyguard.
18167                    mWindowManager.lockNow(null);
18168                } else {
18169                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18170                    updateCurrentProfileIdsLocked();
18171                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18172                    mUserLru.remove(currentUserIdInt);
18173                    mUserLru.add(currentUserIdInt);
18174                }
18175
18176                final UserStartedState uss = mStartedUsers.get(userId);
18177
18178                // Make sure user is in the started state.  If it is currently
18179                // stopping, we need to knock that off.
18180                if (uss.mState == UserStartedState.STATE_STOPPING) {
18181                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18182                    // so we can just fairly silently bring the user back from
18183                    // the almost-dead.
18184                    uss.mState = UserStartedState.STATE_RUNNING;
18185                    updateStartedUserArrayLocked();
18186                    needStart = true;
18187                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18188                    // This means ACTION_SHUTDOWN has been sent, so we will
18189                    // need to treat this as a new boot of the user.
18190                    uss.mState = UserStartedState.STATE_BOOTING;
18191                    updateStartedUserArrayLocked();
18192                    needStart = true;
18193                }
18194
18195                if (uss.mState == UserStartedState.STATE_BOOTING) {
18196                    // Booting up a new user, need to tell system services about it.
18197                    // Note that this is on the same handler as scheduling of broadcasts,
18198                    // which is important because it needs to go first.
18199                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18200                }
18201
18202                if (foreground) {
18203                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18204                            oldUserId));
18205                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18206                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18207                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18208                            oldUserId, userId, uss));
18209                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18210                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18211                }
18212
18213                if (needStart) {
18214                    // Send USER_STARTED broadcast
18215                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18216                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18217                            | Intent.FLAG_RECEIVER_FOREGROUND);
18218                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18219                    broadcastIntentLocked(null, null, intent,
18220                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18221                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18222                }
18223
18224                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18225                    if (userId != UserHandle.USER_OWNER) {
18226                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18227                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18228                        broadcastIntentLocked(null, null, intent, null,
18229                                new IIntentReceiver.Stub() {
18230                                    public void performReceive(Intent intent, int resultCode,
18231                                            String data, Bundle extras, boolean ordered,
18232                                            boolean sticky, int sendingUser) {
18233                                        onUserInitialized(uss, foreground, oldUserId, userId);
18234                                    }
18235                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18236                                true, false, MY_PID, Process.SYSTEM_UID,
18237                                userId);
18238                        uss.initializing = true;
18239                    } else {
18240                        getUserManagerLocked().makeInitialized(userInfo.id);
18241                    }
18242                }
18243
18244                if (foreground) {
18245                    if (!uss.initializing) {
18246                        moveUserToForeground(uss, oldUserId, userId);
18247                    }
18248                } else {
18249                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18250                }
18251
18252                if (needStart) {
18253                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18254                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18255                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18256                    broadcastIntentLocked(null, null, intent,
18257                            null, new IIntentReceiver.Stub() {
18258                                @Override
18259                                public void performReceive(Intent intent, int resultCode, String data,
18260                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18261                                        throws RemoteException {
18262                                }
18263                            }, 0, null, null,
18264                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18265                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18266                }
18267            }
18268        } finally {
18269            Binder.restoreCallingIdentity(ident);
18270        }
18271
18272        return true;
18273    }
18274
18275    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18276        long ident = Binder.clearCallingIdentity();
18277        try {
18278            Intent intent;
18279            if (oldUserId >= 0) {
18280                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18281                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18282                int count = profiles.size();
18283                for (int i = 0; i < count; i++) {
18284                    int profileUserId = profiles.get(i).id;
18285                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18286                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18287                            | Intent.FLAG_RECEIVER_FOREGROUND);
18288                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18289                    broadcastIntentLocked(null, null, intent,
18290                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18291                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18292                }
18293            }
18294            if (newUserId >= 0) {
18295                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18296                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18297                int count = profiles.size();
18298                for (int i = 0; i < count; i++) {
18299                    int profileUserId = profiles.get(i).id;
18300                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18301                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18302                            | Intent.FLAG_RECEIVER_FOREGROUND);
18303                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18304                    broadcastIntentLocked(null, null, intent,
18305                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18306                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18307                }
18308                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18309                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18310                        | Intent.FLAG_RECEIVER_FOREGROUND);
18311                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18312                broadcastIntentLocked(null, null, intent,
18313                        null, null, 0, null, null,
18314                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18315                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18316            }
18317        } finally {
18318            Binder.restoreCallingIdentity(ident);
18319        }
18320    }
18321
18322    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18323            final int newUserId) {
18324        final int N = mUserSwitchObservers.beginBroadcast();
18325        if (N > 0) {
18326            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18327                int mCount = 0;
18328                @Override
18329                public void sendResult(Bundle data) throws RemoteException {
18330                    synchronized (ActivityManagerService.this) {
18331                        if (mCurUserSwitchCallback == this) {
18332                            mCount++;
18333                            if (mCount == N) {
18334                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18335                            }
18336                        }
18337                    }
18338                }
18339            };
18340            synchronized (this) {
18341                uss.switching = true;
18342                mCurUserSwitchCallback = callback;
18343            }
18344            for (int i=0; i<N; i++) {
18345                try {
18346                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18347                            newUserId, callback);
18348                } catch (RemoteException e) {
18349                }
18350            }
18351        } else {
18352            synchronized (this) {
18353                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18354            }
18355        }
18356        mUserSwitchObservers.finishBroadcast();
18357    }
18358
18359    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18360        synchronized (this) {
18361            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18362            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18363        }
18364    }
18365
18366    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18367        mCurUserSwitchCallback = null;
18368        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18369        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18370                oldUserId, newUserId, uss));
18371    }
18372
18373    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18374        synchronized (this) {
18375            if (foreground) {
18376                moveUserToForeground(uss, oldUserId, newUserId);
18377            }
18378        }
18379
18380        completeSwitchAndInitalize(uss, newUserId, true, false);
18381    }
18382
18383    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18384        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18385        if (homeInFront) {
18386            startHomeActivityLocked(newUserId);
18387        } else {
18388            mStackSupervisor.resumeTopActivitiesLocked();
18389        }
18390        EventLogTags.writeAmSwitchUser(newUserId);
18391        getUserManagerLocked().userForeground(newUserId);
18392        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18393    }
18394
18395    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18396        completeSwitchAndInitalize(uss, newUserId, false, true);
18397    }
18398
18399    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18400            boolean clearInitializing, boolean clearSwitching) {
18401        boolean unfrozen = false;
18402        synchronized (this) {
18403            if (clearInitializing) {
18404                uss.initializing = false;
18405                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18406            }
18407            if (clearSwitching) {
18408                uss.switching = false;
18409            }
18410            if (!uss.switching && !uss.initializing) {
18411                mWindowManager.stopFreezingScreen();
18412                unfrozen = true;
18413            }
18414        }
18415        if (unfrozen) {
18416            final int N = mUserSwitchObservers.beginBroadcast();
18417            for (int i=0; i<N; i++) {
18418                try {
18419                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18420                } catch (RemoteException e) {
18421                }
18422            }
18423            mUserSwitchObservers.finishBroadcast();
18424        }
18425    }
18426
18427    void scheduleStartProfilesLocked() {
18428        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18429            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18430                    DateUtils.SECOND_IN_MILLIS);
18431        }
18432    }
18433
18434    void startProfilesLocked() {
18435        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18436        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18437                mCurrentUserId, false /* enabledOnly */);
18438        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18439        for (UserInfo user : profiles) {
18440            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18441                    && user.id != mCurrentUserId) {
18442                toStart.add(user);
18443            }
18444        }
18445        final int n = toStart.size();
18446        int i = 0;
18447        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18448            startUserInBackground(toStart.get(i).id);
18449        }
18450        if (i < n) {
18451            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18452        }
18453    }
18454
18455    void finishUserBoot(UserStartedState uss) {
18456        synchronized (this) {
18457            if (uss.mState == UserStartedState.STATE_BOOTING
18458                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18459                uss.mState = UserStartedState.STATE_RUNNING;
18460                final int userId = uss.mHandle.getIdentifier();
18461                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18462                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18463                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18464                broadcastIntentLocked(null, null, intent,
18465                        null, null, 0, null, null,
18466                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18467                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18468            }
18469        }
18470    }
18471
18472    void finishUserSwitch(UserStartedState uss) {
18473        synchronized (this) {
18474            finishUserBoot(uss);
18475
18476            startProfilesLocked();
18477
18478            int num = mUserLru.size();
18479            int i = 0;
18480            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18481                Integer oldUserId = mUserLru.get(i);
18482                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18483                if (oldUss == null) {
18484                    // Shouldn't happen, but be sane if it does.
18485                    mUserLru.remove(i);
18486                    num--;
18487                    continue;
18488                }
18489                if (oldUss.mState == UserStartedState.STATE_STOPPING
18490                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18491                    // This user is already stopping, doesn't count.
18492                    num--;
18493                    i++;
18494                    continue;
18495                }
18496                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18497                    // Owner and current can't be stopped, but count as running.
18498                    i++;
18499                    continue;
18500                }
18501                // This is a user to be stopped.
18502                stopUserLocked(oldUserId, null);
18503                num--;
18504                i++;
18505            }
18506        }
18507    }
18508
18509    @Override
18510    public int stopUser(final int userId, final IStopUserCallback callback) {
18511        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18512                != PackageManager.PERMISSION_GRANTED) {
18513            String msg = "Permission Denial: switchUser() from pid="
18514                    + Binder.getCallingPid()
18515                    + ", uid=" + Binder.getCallingUid()
18516                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18517            Slog.w(TAG, msg);
18518            throw new SecurityException(msg);
18519        }
18520        if (userId <= 0) {
18521            throw new IllegalArgumentException("Can't stop primary user " + userId);
18522        }
18523        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18524        synchronized (this) {
18525            return stopUserLocked(userId, callback);
18526        }
18527    }
18528
18529    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18530        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18531        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18532            return ActivityManager.USER_OP_IS_CURRENT;
18533        }
18534
18535        final UserStartedState uss = mStartedUsers.get(userId);
18536        if (uss == null) {
18537            // User is not started, nothing to do...  but we do need to
18538            // callback if requested.
18539            if (callback != null) {
18540                mHandler.post(new Runnable() {
18541                    @Override
18542                    public void run() {
18543                        try {
18544                            callback.userStopped(userId);
18545                        } catch (RemoteException e) {
18546                        }
18547                    }
18548                });
18549            }
18550            return ActivityManager.USER_OP_SUCCESS;
18551        }
18552
18553        if (callback != null) {
18554            uss.mStopCallbacks.add(callback);
18555        }
18556
18557        if (uss.mState != UserStartedState.STATE_STOPPING
18558                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18559            uss.mState = UserStartedState.STATE_STOPPING;
18560            updateStartedUserArrayLocked();
18561
18562            long ident = Binder.clearCallingIdentity();
18563            try {
18564                // We are going to broadcast ACTION_USER_STOPPING and then
18565                // once that is done send a final ACTION_SHUTDOWN and then
18566                // stop the user.
18567                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18568                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18569                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18570                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18571                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18572                // This is the result receiver for the final shutdown broadcast.
18573                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18574                    @Override
18575                    public void performReceive(Intent intent, int resultCode, String data,
18576                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18577                        finishUserStop(uss);
18578                    }
18579                };
18580                // This is the result receiver for the initial stopping broadcast.
18581                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18582                    @Override
18583                    public void performReceive(Intent intent, int resultCode, String data,
18584                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18585                        // On to the next.
18586                        synchronized (ActivityManagerService.this) {
18587                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18588                                // Whoops, we are being started back up.  Abort, abort!
18589                                return;
18590                            }
18591                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18592                        }
18593                        mBatteryStatsService.noteEvent(
18594                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18595                                Integer.toString(userId), userId);
18596                        mSystemServiceManager.stopUser(userId);
18597                        broadcastIntentLocked(null, null, shutdownIntent,
18598                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18599                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18600                    }
18601                };
18602                // Kick things off.
18603                broadcastIntentLocked(null, null, stoppingIntent,
18604                        null, stoppingReceiver, 0, null, null,
18605                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18606                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18607            } finally {
18608                Binder.restoreCallingIdentity(ident);
18609            }
18610        }
18611
18612        return ActivityManager.USER_OP_SUCCESS;
18613    }
18614
18615    void finishUserStop(UserStartedState uss) {
18616        final int userId = uss.mHandle.getIdentifier();
18617        boolean stopped;
18618        ArrayList<IStopUserCallback> callbacks;
18619        synchronized (this) {
18620            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18621            if (mStartedUsers.get(userId) != uss) {
18622                stopped = false;
18623            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18624                stopped = false;
18625            } else {
18626                stopped = true;
18627                // User can no longer run.
18628                mStartedUsers.remove(userId);
18629                mUserLru.remove(Integer.valueOf(userId));
18630                updateStartedUserArrayLocked();
18631
18632                // Clean up all state and processes associated with the user.
18633                // Kill all the processes for the user.
18634                forceStopUserLocked(userId, "finish user");
18635            }
18636
18637            // Explicitly remove the old information in mRecentTasks.
18638            removeRecentTasksForUserLocked(userId);
18639        }
18640
18641        for (int i=0; i<callbacks.size(); i++) {
18642            try {
18643                if (stopped) callbacks.get(i).userStopped(userId);
18644                else callbacks.get(i).userStopAborted(userId);
18645            } catch (RemoteException e) {
18646            }
18647        }
18648
18649        if (stopped) {
18650            mSystemServiceManager.cleanupUser(userId);
18651            synchronized (this) {
18652                mStackSupervisor.removeUserLocked(userId);
18653            }
18654        }
18655    }
18656
18657    @Override
18658    public UserInfo getCurrentUser() {
18659        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18660                != PackageManager.PERMISSION_GRANTED) && (
18661                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18662                != PackageManager.PERMISSION_GRANTED)) {
18663            String msg = "Permission Denial: getCurrentUser() from pid="
18664                    + Binder.getCallingPid()
18665                    + ", uid=" + Binder.getCallingUid()
18666                    + " requires " + INTERACT_ACROSS_USERS;
18667            Slog.w(TAG, msg);
18668            throw new SecurityException(msg);
18669        }
18670        synchronized (this) {
18671            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18672            return getUserManagerLocked().getUserInfo(userId);
18673        }
18674    }
18675
18676    int getCurrentUserIdLocked() {
18677        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18678    }
18679
18680    @Override
18681    public boolean isUserRunning(int userId, boolean orStopped) {
18682        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18683                != PackageManager.PERMISSION_GRANTED) {
18684            String msg = "Permission Denial: isUserRunning() from pid="
18685                    + Binder.getCallingPid()
18686                    + ", uid=" + Binder.getCallingUid()
18687                    + " requires " + INTERACT_ACROSS_USERS;
18688            Slog.w(TAG, msg);
18689            throw new SecurityException(msg);
18690        }
18691        synchronized (this) {
18692            return isUserRunningLocked(userId, orStopped);
18693        }
18694    }
18695
18696    boolean isUserRunningLocked(int userId, boolean orStopped) {
18697        UserStartedState state = mStartedUsers.get(userId);
18698        if (state == null) {
18699            return false;
18700        }
18701        if (orStopped) {
18702            return true;
18703        }
18704        return state.mState != UserStartedState.STATE_STOPPING
18705                && state.mState != UserStartedState.STATE_SHUTDOWN;
18706    }
18707
18708    @Override
18709    public int[] getRunningUserIds() {
18710        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18711                != PackageManager.PERMISSION_GRANTED) {
18712            String msg = "Permission Denial: isUserRunning() from pid="
18713                    + Binder.getCallingPid()
18714                    + ", uid=" + Binder.getCallingUid()
18715                    + " requires " + INTERACT_ACROSS_USERS;
18716            Slog.w(TAG, msg);
18717            throw new SecurityException(msg);
18718        }
18719        synchronized (this) {
18720            return mStartedUserArray;
18721        }
18722    }
18723
18724    private void updateStartedUserArrayLocked() {
18725        int num = 0;
18726        for (int i=0; i<mStartedUsers.size();  i++) {
18727            UserStartedState uss = mStartedUsers.valueAt(i);
18728            // This list does not include stopping users.
18729            if (uss.mState != UserStartedState.STATE_STOPPING
18730                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18731                num++;
18732            }
18733        }
18734        mStartedUserArray = new int[num];
18735        num = 0;
18736        for (int i=0; i<mStartedUsers.size();  i++) {
18737            UserStartedState uss = mStartedUsers.valueAt(i);
18738            if (uss.mState != UserStartedState.STATE_STOPPING
18739                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18740                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18741                num++;
18742            }
18743        }
18744    }
18745
18746    @Override
18747    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18748        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18749                != PackageManager.PERMISSION_GRANTED) {
18750            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18751                    + Binder.getCallingPid()
18752                    + ", uid=" + Binder.getCallingUid()
18753                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18754            Slog.w(TAG, msg);
18755            throw new SecurityException(msg);
18756        }
18757
18758        mUserSwitchObservers.register(observer);
18759    }
18760
18761    @Override
18762    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18763        mUserSwitchObservers.unregister(observer);
18764    }
18765
18766    private boolean userExists(int userId) {
18767        if (userId == 0) {
18768            return true;
18769        }
18770        UserManagerService ums = getUserManagerLocked();
18771        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18772    }
18773
18774    int[] getUsersLocked() {
18775        UserManagerService ums = getUserManagerLocked();
18776        return ums != null ? ums.getUserIds() : new int[] { 0 };
18777    }
18778
18779    UserManagerService getUserManagerLocked() {
18780        if (mUserManager == null) {
18781            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18782            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18783        }
18784        return mUserManager;
18785    }
18786
18787    private int applyUserId(int uid, int userId) {
18788        return UserHandle.getUid(userId, uid);
18789    }
18790
18791    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18792        if (info == null) return null;
18793        ApplicationInfo newInfo = new ApplicationInfo(info);
18794        newInfo.uid = applyUserId(info.uid, userId);
18795        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18796                + info.packageName;
18797        return newInfo;
18798    }
18799
18800    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18801        if (aInfo == null
18802                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18803            return aInfo;
18804        }
18805
18806        ActivityInfo info = new ActivityInfo(aInfo);
18807        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18808        return info;
18809    }
18810
18811    private final class LocalService extends ActivityManagerInternal {
18812        @Override
18813        public void goingToSleep() {
18814            ActivityManagerService.this.goingToSleep();
18815        }
18816
18817        @Override
18818        public void wakingUp() {
18819            ActivityManagerService.this.wakingUp();
18820        }
18821
18822        @Override
18823        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18824                String processName, String abiOverride, int uid, Runnable crashHandler) {
18825            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18826                    processName, abiOverride, uid, crashHandler);
18827        }
18828    }
18829
18830    /**
18831     * An implementation of IAppTask, that allows an app to manage its own tasks via
18832     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18833     * only the process that calls getAppTasks() can call the AppTask methods.
18834     */
18835    class AppTaskImpl extends IAppTask.Stub {
18836        private int mTaskId;
18837        private int mCallingUid;
18838
18839        public AppTaskImpl(int taskId, int callingUid) {
18840            mTaskId = taskId;
18841            mCallingUid = callingUid;
18842        }
18843
18844        private void checkCaller() {
18845            if (mCallingUid != Binder.getCallingUid()) {
18846                throw new SecurityException("Caller " + mCallingUid
18847                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18848            }
18849        }
18850
18851        @Override
18852        public void finishAndRemoveTask() {
18853            checkCaller();
18854
18855            synchronized (ActivityManagerService.this) {
18856                long origId = Binder.clearCallingIdentity();
18857                try {
18858                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18859                    if (tr == null) {
18860                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18861                    }
18862                    // Only kill the process if we are not a new document
18863                    int flags = tr.getBaseIntent().getFlags();
18864                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18865                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18866                    removeTaskByIdLocked(mTaskId,
18867                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18868                } finally {
18869                    Binder.restoreCallingIdentity(origId);
18870                }
18871            }
18872        }
18873
18874        @Override
18875        public ActivityManager.RecentTaskInfo getTaskInfo() {
18876            checkCaller();
18877
18878            synchronized (ActivityManagerService.this) {
18879                long origId = Binder.clearCallingIdentity();
18880                try {
18881                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18882                    if (tr == null) {
18883                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18884                    }
18885                    return createRecentTaskInfoFromTaskRecord(tr);
18886                } finally {
18887                    Binder.restoreCallingIdentity(origId);
18888                }
18889            }
18890        }
18891
18892        @Override
18893        public void moveToFront() {
18894            checkCaller();
18895
18896            final TaskRecord tr;
18897            synchronized (ActivityManagerService.this) {
18898                tr = recentTaskForIdLocked(mTaskId);
18899                if (tr == null) {
18900                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18901                }
18902                if (tr.getRootActivity() != null) {
18903                    long origId = Binder.clearCallingIdentity();
18904                    try {
18905                        moveTaskToFrontLocked(tr.taskId, 0, null);
18906                        return;
18907                    } finally {
18908                        Binder.restoreCallingIdentity(origId);
18909                    }
18910                }
18911            }
18912
18913            startActivityFromRecentsInner(tr.taskId, null);
18914        }
18915
18916        @Override
18917        public int startActivity(IBinder whoThread, String callingPackage,
18918                Intent intent, String resolvedType, Bundle options) {
18919            checkCaller();
18920
18921            int callingUser = UserHandle.getCallingUserId();
18922            TaskRecord tr;
18923            IApplicationThread appThread;
18924            synchronized (ActivityManagerService.this) {
18925                tr = recentTaskForIdLocked(mTaskId);
18926                if (tr == null) {
18927                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18928                }
18929                appThread = ApplicationThreadNative.asInterface(whoThread);
18930                if (appThread == null) {
18931                    throw new IllegalArgumentException("Bad app thread " + appThread);
18932                }
18933            }
18934            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18935                    resolvedType, null, null, null, null, 0, 0, null, null,
18936                    null, options, callingUser, null, tr);
18937        }
18938
18939        @Override
18940        public void setExcludeFromRecents(boolean exclude) {
18941            checkCaller();
18942
18943            synchronized (ActivityManagerService.this) {
18944                long origId = Binder.clearCallingIdentity();
18945                try {
18946                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18947                    if (tr == null) {
18948                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18949                    }
18950                    Intent intent = tr.getBaseIntent();
18951                    if (exclude) {
18952                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18953                    } else {
18954                        intent.setFlags(intent.getFlags()
18955                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18956                    }
18957                } finally {
18958                    Binder.restoreCallingIdentity(origId);
18959                }
18960            }
18961        }
18962    }
18963}
18964