ActivityManagerService.java revision 7f61e96db7c90c1f4418359672aa4656aebee500
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.provider.Settings;
184import android.text.format.DateUtils;
185import android.text.format.Time;
186import android.util.AtomicFile;
187import android.util.EventLog;
188import android.util.Log;
189import android.util.Pair;
190import android.util.PrintWriterPrinter;
191import android.util.Slog;
192import android.util.SparseArray;
193import android.util.TimeUtils;
194import android.util.Xml;
195import android.view.Gravity;
196import android.view.LayoutInflater;
197import android.view.View;
198import android.view.WindowManager;
199
200import java.io.BufferedInputStream;
201import java.io.BufferedOutputStream;
202import java.io.DataInputStream;
203import java.io.DataOutputStream;
204import java.io.File;
205import java.io.FileDescriptor;
206import java.io.FileInputStream;
207import java.io.FileNotFoundException;
208import java.io.FileOutputStream;
209import java.io.IOException;
210import java.io.InputStreamReader;
211import java.io.PrintWriter;
212import java.io.StringWriter;
213import java.lang.ref.WeakReference;
214import java.util.ArrayList;
215import java.util.Arrays;
216import java.util.Collections;
217import java.util.Comparator;
218import java.util.HashMap;
219import java.util.HashSet;
220import java.util.Iterator;
221import java.util.List;
222import java.util.Locale;
223import java.util.Map;
224import java.util.Set;
225import java.util.concurrent.atomic.AtomicBoolean;
226import java.util.concurrent.atomic.AtomicLong;
227
228public final class ActivityManagerService extends ActivityManagerNative
229        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
230
231    private static final String USER_DATA_DIR = "/data/user/";
232    // File that stores last updated system version and called preboot receivers
233    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
234
235    static final String TAG = "ActivityManager";
236    static final String TAG_MU = "ActivityManagerServiceMU";
237    static final boolean DEBUG = false;
238    static final boolean localLOGV = DEBUG;
239    static final boolean DEBUG_BACKUP = localLOGV || false;
240    static final boolean DEBUG_BROADCAST = localLOGV || false;
241    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
242    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
243    static final boolean DEBUG_CLEANUP = localLOGV || false;
244    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
245    static final boolean DEBUG_FOCUS = false;
246    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
247    static final boolean DEBUG_MU = localLOGV || false;
248    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
249    static final boolean DEBUG_LRU = localLOGV || false;
250    static final boolean DEBUG_PAUSE = localLOGV || false;
251    static final boolean DEBUG_POWER = localLOGV || false;
252    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
253    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
254    static final boolean DEBUG_PROCESSES = localLOGV || false;
255    static final boolean DEBUG_PROVIDER = localLOGV || false;
256    static final boolean DEBUG_RESULTS = localLOGV || false;
257    static final boolean DEBUG_SERVICE = localLOGV || false;
258    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
259    static final boolean DEBUG_STACK = localLOGV || false;
260    static final boolean DEBUG_SWITCH = localLOGV || false;
261    static final boolean DEBUG_TASKS = localLOGV || false;
262    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
263    static final boolean DEBUG_TRANSITION = localLOGV || false;
264    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
265    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
266    static final boolean DEBUG_VISBILITY = localLOGV || false;
267    static final boolean DEBUG_PSS = localLOGV || false;
268    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
269    static final boolean DEBUG_RECENTS = localLOGV || false;
270    static final boolean VALIDATE_TOKENS = false;
271    static final boolean SHOW_ACTIVITY_START_TIME = true;
272
273    // Control over CPU and battery monitoring.
274    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
275    static final boolean MONITOR_CPU_USAGE = true;
276    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
277    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
278    static final boolean MONITOR_THREAD_CPU_USAGE = false;
279
280    // The flags that are set for all calls we make to the package manager.
281    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
282
283    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
284
285    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
286
287    // Maximum number recent bitmaps to keep in memory.
288    static final int MAX_RECENT_BITMAPS = 5;
289
290    // Amount of time after a call to stopAppSwitches() during which we will
291    // prevent further untrusted switches from happening.
292    static final long APP_SWITCH_DELAY_TIME = 5*1000;
293
294    // How long we wait for a launched process to attach to the activity manager
295    // before we decide it's never going to come up for real.
296    static final int PROC_START_TIMEOUT = 10*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real, when the process was
300    // started with a wrapper for instrumentation (such as Valgrind) because it
301    // could take much longer than usual.
302    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
303
304    // How long to wait after going idle before forcing apps to GC.
305    static final int GC_TIMEOUT = 5*1000;
306
307    // The minimum amount of time between successive GC requests for a process.
308    static final int GC_MIN_INTERVAL = 60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process.
311    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
312
313    // The minimum amount of time between successive PSS requests for a process
314    // when the request is due to the memory state being lowered.
315    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
316
317    // The rate at which we check for apps using excessive power -- 15 mins.
318    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
319
320    // The minimum sample duration we will allow before deciding we have
321    // enough data on wake locks to start killing things.
322    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on CPU usage to start killing things.
326    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // How long we allow a receiver to run before giving up on it.
329    static final int BROADCAST_FG_TIMEOUT = 10*1000;
330    static final int BROADCAST_BG_TIMEOUT = 60*1000;
331
332    // How long we wait until we timeout on key dispatching.
333    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
334
335    // How long we wait until we timeout on key dispatching during instrumentation.
336    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
337
338    // Amount of time we wait for observers to handle a user switch before
339    // giving up on them and unfreezing the screen.
340    static final int USER_SWITCH_TIMEOUT = 2*1000;
341
342    // Maximum number of users we allow to be running at a time.
343    static final int MAX_RUNNING_USERS = 3;
344
345    // How long to wait in getAssistContextExtras for the activity and foreground services
346    // to respond with the result.
347    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
348
349    // Maximum number of persisted Uri grants a package is allowed
350    static final int MAX_PERSISTED_URI_GRANTS = 128;
351
352    static final int MY_PID = Process.myPid();
353
354    static final String[] EMPTY_STRING_ARRAY = new String[0];
355
356    // How many bytes to write into the dropbox log before truncating
357    static final int DROPBOX_MAX_SIZE = 256 * 1024;
358
359    // Access modes for handleIncomingUser.
360    static final int ALLOW_NON_FULL = 0;
361    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
362    static final int ALLOW_FULL_ONLY = 2;
363
364    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
365
366    /** All system services */
367    SystemServiceManager mSystemServiceManager;
368
369    /** Run all ActivityStacks through this */
370    ActivityStackSupervisor mStackSupervisor;
371
372    public IntentFirewall mIntentFirewall;
373
374    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
375    // default actuion automatically.  Important for devices without direct input
376    // devices.
377    private boolean mShowDialogs = true;
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
415
416    /**
417     * For addAppTask: cached of the last activity component that was added.
418     */
419    ComponentName mLastAddedTaskComponent;
420
421    /**
422     * For addAppTask: cached of the last activity uid that was added.
423     */
424    int mLastAddedTaskUid;
425
426    /**
427     * For addAppTask: cached of the last ActivityInfo that was added.
428     */
429    ActivityInfo mLastAddedTaskActivity;
430
431    public class PendingAssistExtras extends Binder implements Runnable {
432        public final ActivityRecord activity;
433        public boolean haveResult = false;
434        public Bundle result = null;
435        public PendingAssistExtras(ActivityRecord _activity) {
436            activity = _activity;
437        }
438        @Override
439        public void run() {
440            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
441            synchronized (this) {
442                haveResult = true;
443                notifyAll();
444            }
445        }
446    }
447
448    final ArrayList<PendingAssistExtras> mPendingAssistExtras
449            = new ArrayList<PendingAssistExtras>();
450
451    /**
452     * Process management.
453     */
454    final ProcessList mProcessList = new ProcessList();
455
456    /**
457     * All of the applications we currently have running organized by name.
458     * The keys are strings of the application package name (as
459     * returned by the package manager), and the keys are ApplicationRecord
460     * objects.
461     */
462    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
463
464    /**
465     * Tracking long-term execution of processes to look for abuse and other
466     * bad app behavior.
467     */
468    final ProcessStatsService mProcessStats;
469
470    /**
471     * The currently running isolated processes.
472     */
473    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
474
475    /**
476     * Counter for assigning isolated process uids, to avoid frequently reusing the
477     * same ones.
478     */
479    int mNextIsolatedProcessUid = 0;
480
481    /**
482     * The currently running heavy-weight process, if any.
483     */
484    ProcessRecord mHeavyWeightProcess = null;
485
486    /**
487     * The last time that various processes have crashed.
488     */
489    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
490
491    /**
492     * Information about a process that is currently marked as bad.
493     */
494    static final class BadProcessInfo {
495        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
496            this.time = time;
497            this.shortMsg = shortMsg;
498            this.longMsg = longMsg;
499            this.stack = stack;
500        }
501
502        final long time;
503        final String shortMsg;
504        final String longMsg;
505        final String stack;
506    }
507
508    /**
509     * Set of applications that we consider to be bad, and will reject
510     * incoming broadcasts from (which the user has no control over).
511     * Processes are added to this set when they have crashed twice within
512     * a minimum amount of time; they are removed from it when they are
513     * later restarted (hopefully due to some user action).  The value is the
514     * time it was added to the list.
515     */
516    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
517
518    /**
519     * All of the processes we currently have running organized by pid.
520     * The keys are the pid running the application.
521     *
522     * <p>NOTE: This object is protected by its own lock, NOT the global
523     * activity manager lock!
524     */
525    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
526
527    /**
528     * All of the processes that have been forced to be foreground.  The key
529     * is the pid of the caller who requested it (we hold a death
530     * link on it).
531     */
532    abstract class ForegroundToken implements IBinder.DeathRecipient {
533        int pid;
534        IBinder token;
535    }
536    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
537
538    /**
539     * List of records for processes that someone had tried to start before the
540     * system was ready.  We don't start them at that point, but ensure they
541     * are started by the time booting is complete.
542     */
543    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
544
545    /**
546     * List of persistent applications that are in the process
547     * of being started.
548     */
549    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
550
551    /**
552     * Processes that are being forcibly torn down.
553     */
554    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
555
556    /**
557     * List of running applications, sorted by recent usage.
558     * The first entry in the list is the least recently used.
559     */
560    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
561
562    /**
563     * Where in mLruProcesses that the processes hosting activities start.
564     */
565    int mLruProcessActivityStart = 0;
566
567    /**
568     * Where in mLruProcesses that the processes hosting services start.
569     * This is after (lower index) than mLruProcessesActivityStart.
570     */
571    int mLruProcessServiceStart = 0;
572
573    /**
574     * List of processes that should gc as soon as things are idle.
575     */
576    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes we want to collect PSS data from.
580     */
581    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * Last time we requested PSS data of all processes.
585     */
586    long mLastFullPssTime = SystemClock.uptimeMillis();
587
588    /**
589     * If set, the next time we collect PSS data we should do a full collection
590     * with data from native processes and the kernel.
591     */
592    boolean mFullPssPending = false;
593
594    /**
595     * This is the process holding what we currently consider to be
596     * the "home" activity.
597     */
598    ProcessRecord mHomeProcess;
599
600    /**
601     * This is the process holding the activity the user last visited that
602     * is in a different process from the one they are currently in.
603     */
604    ProcessRecord mPreviousProcess;
605
606    /**
607     * The time at which the previous process was last visible.
608     */
609    long mPreviousProcessVisibleTime;
610
611    /**
612     * Which uses have been started, so are allowed to run code.
613     */
614    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
615
616    /**
617     * LRU list of history of current users.  Most recently current is at the end.
618     */
619    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
620
621    /**
622     * Constant array of the users that are currently started.
623     */
624    int[] mStartedUserArray = new int[] { 0 };
625
626    /**
627     * Registered observers of the user switching mechanics.
628     */
629    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
630            = new RemoteCallbackList<IUserSwitchObserver>();
631
632    /**
633     * Currently active user switch.
634     */
635    Object mCurUserSwitchCallback;
636
637    /**
638     * Packages that the user has asked to have run in screen size
639     * compatibility mode instead of filling the screen.
640     */
641    final CompatModePackages mCompatModePackages;
642
643    /**
644     * Set of IntentSenderRecord objects that are currently active.
645     */
646    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
647            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
648
649    /**
650     * Fingerprints (hashCode()) of stack traces that we've
651     * already logged DropBox entries for.  Guarded by itself.  If
652     * something (rogue user app) forces this over
653     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
654     */
655    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
656    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
657
658    /**
659     * Strict Mode background batched logging state.
660     *
661     * The string buffer is guarded by itself, and its lock is also
662     * used to determine if another batched write is already
663     * in-flight.
664     */
665    private final StringBuilder mStrictModeBuffer = new StringBuilder();
666
667    /**
668     * Keeps track of all IIntentReceivers that have been registered for
669     * broadcasts.  Hash keys are the receiver IBinder, hash value is
670     * a ReceiverList.
671     */
672    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
673            new HashMap<IBinder, ReceiverList>();
674
675    /**
676     * Resolver for broadcast intents to registered receivers.
677     * Holds BroadcastFilter (subclass of IntentFilter).
678     */
679    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
680            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
681        @Override
682        protected boolean allowFilterResult(
683                BroadcastFilter filter, List<BroadcastFilter> dest) {
684            IBinder target = filter.receiverList.receiver.asBinder();
685            for (int i=dest.size()-1; i>=0; i--) {
686                if (dest.get(i).receiverList.receiver.asBinder() == target) {
687                    return false;
688                }
689            }
690            return true;
691        }
692
693        @Override
694        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
695            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
696                    || userId == filter.owningUserId) {
697                return super.newResult(filter, match, userId);
698            }
699            return null;
700        }
701
702        @Override
703        protected BroadcastFilter[] newArray(int size) {
704            return new BroadcastFilter[size];
705        }
706
707        @Override
708        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
709            return packageName.equals(filter.packageName);
710        }
711    };
712
713    /**
714     * State of all active sticky broadcasts per user.  Keys are the action of the
715     * sticky Intent, values are an ArrayList of all broadcasted intents with
716     * that action (which should usually be one).  The SparseArray is keyed
717     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
718     * for stickies that are sent to all users.
719     */
720    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
721            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
722
723    final ActiveServices mServices;
724
725    /**
726     * Backup/restore process management
727     */
728    String mBackupAppName = null;
729    BackupRecord mBackupTarget = null;
730
731    final ProviderMap mProviderMap;
732
733    /**
734     * List of content providers who have clients waiting for them.  The
735     * application is currently being launched and the provider will be
736     * removed from this list once it is published.
737     */
738    final ArrayList<ContentProviderRecord> mLaunchingProviders
739            = new ArrayList<ContentProviderRecord>();
740
741    /**
742     * File storing persisted {@link #mGrantedUriPermissions}.
743     */
744    private final AtomicFile mGrantFile;
745
746    /** XML constants used in {@link #mGrantFile} */
747    private static final String TAG_URI_GRANTS = "uri-grants";
748    private static final String TAG_URI_GRANT = "uri-grant";
749    private static final String ATTR_USER_HANDLE = "userHandle";
750    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
751    private static final String ATTR_TARGET_USER_ID = "targetUserId";
752    private static final String ATTR_SOURCE_PKG = "sourcePkg";
753    private static final String ATTR_TARGET_PKG = "targetPkg";
754    private static final String ATTR_URI = "uri";
755    private static final String ATTR_MODE_FLAGS = "modeFlags";
756    private static final String ATTR_CREATED_TIME = "createdTime";
757    private static final String ATTR_PREFIX = "prefix";
758
759    /**
760     * Global set of specific {@link Uri} permissions that have been granted.
761     * This optimized lookup structure maps from {@link UriPermission#targetUid}
762     * to {@link UriPermission#uri} to {@link UriPermission}.
763     */
764    @GuardedBy("this")
765    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
766            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
767
768    public static class GrantUri {
769        public final int sourceUserId;
770        public final Uri uri;
771        public boolean prefix;
772
773        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
774            this.sourceUserId = sourceUserId;
775            this.uri = uri;
776            this.prefix = prefix;
777        }
778
779        @Override
780        public int hashCode() {
781            return toString().hashCode();
782        }
783
784        @Override
785        public boolean equals(Object o) {
786            if (o instanceof GrantUri) {
787                GrantUri other = (GrantUri) o;
788                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
789                        && prefix == other.prefix;
790            }
791            return false;
792        }
793
794        @Override
795        public String toString() {
796            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
797            if (prefix) result += " [prefix]";
798            return result;
799        }
800
801        public String toSafeString() {
802            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
803            if (prefix) result += " [prefix]";
804            return result;
805        }
806
807        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
808            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
809                    ContentProvider.getUriWithoutUserId(uri), false);
810        }
811    }
812
813    CoreSettingsObserver mCoreSettingsObserver;
814
815    /**
816     * Thread-local storage used to carry caller permissions over through
817     * indirect content-provider access.
818     */
819    private class Identity {
820        public int pid;
821        public int uid;
822
823        Identity(int _pid, int _uid) {
824            pid = _pid;
825            uid = _uid;
826        }
827    }
828
829    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
830
831    /**
832     * All information we have collected about the runtime performance of
833     * any user id that can impact battery performance.
834     */
835    final BatteryStatsService mBatteryStatsService;
836
837    /**
838     * Information about component usage
839     */
840    UsageStatsManagerInternal mUsageStatsService;
841
842    /**
843     * Information about and control over application operations
844     */
845    final AppOpsService mAppOpsService;
846
847    /**
848     * Save recent tasks information across reboots.
849     */
850    final TaskPersister mTaskPersister;
851
852    /**
853     * Current configuration information.  HistoryRecord objects are given
854     * a reference to this object to indicate which configuration they are
855     * currently running in, so this object must be kept immutable.
856     */
857    Configuration mConfiguration = new Configuration();
858
859    /**
860     * Current sequencing integer of the configuration, for skipping old
861     * configurations.
862     */
863    int mConfigurationSeq = 0;
864
865    /**
866     * Hardware-reported OpenGLES version.
867     */
868    final int GL_ES_VERSION;
869
870    /**
871     * List of initialization arguments to pass to all processes when binding applications to them.
872     * For example, references to the commonly used services.
873     */
874    HashMap<String, IBinder> mAppBindArgs;
875
876    /**
877     * Temporary to avoid allocations.  Protected by main lock.
878     */
879    final StringBuilder mStringBuilder = new StringBuilder(256);
880
881    /**
882     * Used to control how we initialize the service.
883     */
884    ComponentName mTopComponent;
885    String mTopAction = Intent.ACTION_MAIN;
886    String mTopData;
887    boolean mProcessesReady = false;
888    boolean mSystemReady = false;
889    boolean mBooting = false;
890    boolean mWaitingUpdate = false;
891    boolean mDidUpdate = false;
892    boolean mOnBattery = false;
893    boolean mLaunchWarningShown = false;
894
895    Context mContext;
896
897    int mFactoryTest;
898
899    boolean mCheckedForSetup;
900
901    /**
902     * The time at which we will allow normal application switches again,
903     * after a call to {@link #stopAppSwitches()}.
904     */
905    long mAppSwitchesAllowedTime;
906
907    /**
908     * This is set to true after the first switch after mAppSwitchesAllowedTime
909     * is set; any switches after that will clear the time.
910     */
911    boolean mDidAppSwitch;
912
913    /**
914     * Last time (in realtime) at which we checked for power usage.
915     */
916    long mLastPowerCheckRealtime;
917
918    /**
919     * Last time (in uptime) at which we checked for power usage.
920     */
921    long mLastPowerCheckUptime;
922
923    /**
924     * Set while we are wanting to sleep, to prevent any
925     * activities from being started/resumed.
926     */
927    private boolean mSleeping = false;
928
929    /**
930     * Set while we are running a voice interaction.  This overrides
931     * sleeping while it is active.
932     */
933    private boolean mRunningVoice = false;
934
935    /**
936     * State of external calls telling us if the device is asleep.
937     */
938    private boolean mWentToSleep = false;
939
940    /**
941     * State of external call telling us if the lock screen is shown.
942     */
943    private boolean mLockScreenShown = false;
944
945    /**
946     * Set if we are shutting down the system, similar to sleeping.
947     */
948    boolean mShuttingDown = false;
949
950    /**
951     * Current sequence id for oom_adj computation traversal.
952     */
953    int mAdjSeq = 0;
954
955    /**
956     * Current sequence id for process LRU updating.
957     */
958    int mLruSeq = 0;
959
960    /**
961     * Keep track of the non-cached/empty process we last found, to help
962     * determine how to distribute cached/empty processes next time.
963     */
964    int mNumNonCachedProcs = 0;
965
966    /**
967     * Keep track of the number of cached hidden procs, to balance oom adj
968     * distribution between those and empty procs.
969     */
970    int mNumCachedHiddenProcs = 0;
971
972    /**
973     * Keep track of the number of service processes we last found, to
974     * determine on the next iteration which should be B services.
975     */
976    int mNumServiceProcs = 0;
977    int mNewNumAServiceProcs = 0;
978    int mNewNumServiceProcs = 0;
979
980    /**
981     * Allow the current computed overall memory level of the system to go down?
982     * This is set to false when we are killing processes for reasons other than
983     * memory management, so that the now smaller process list will not be taken as
984     * an indication that memory is tighter.
985     */
986    boolean mAllowLowerMemLevel = false;
987
988    /**
989     * The last computed memory level, for holding when we are in a state that
990     * processes are going away for other reasons.
991     */
992    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
993
994    /**
995     * The last total number of process we have, to determine if changes actually look
996     * like a shrinking number of process due to lower RAM.
997     */
998    int mLastNumProcesses;
999
1000    /**
1001     * The uptime of the last time we performed idle maintenance.
1002     */
1003    long mLastIdleTime = SystemClock.uptimeMillis();
1004
1005    /**
1006     * Total time spent with RAM that has been added in the past since the last idle time.
1007     */
1008    long mLowRamTimeSinceLastIdle = 0;
1009
1010    /**
1011     * If RAM is currently low, when that horrible situation started.
1012     */
1013    long mLowRamStartTime = 0;
1014
1015    /**
1016     * For reporting to battery stats the current top application.
1017     */
1018    private String mCurResumedPackage = null;
1019    private int mCurResumedUid = -1;
1020
1021    /**
1022     * For reporting to battery stats the apps currently running foreground
1023     * service.  The ProcessMap is package/uid tuples; each of these contain
1024     * an array of the currently foreground processes.
1025     */
1026    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1027            = new ProcessMap<ArrayList<ProcessRecord>>();
1028
1029    /**
1030     * This is set if we had to do a delayed dexopt of an app before launching
1031     * it, to increase the ANR timeouts in that case.
1032     */
1033    boolean mDidDexOpt;
1034
1035    /**
1036     * Set if the systemServer made a call to enterSafeMode.
1037     */
1038    boolean mSafeMode;
1039
1040    String mDebugApp = null;
1041    boolean mWaitForDebugger = false;
1042    boolean mDebugTransient = false;
1043    String mOrigDebugApp = null;
1044    boolean mOrigWaitForDebugger = false;
1045    boolean mAlwaysFinishActivities = false;
1046    IActivityController mController = null;
1047    String mProfileApp = null;
1048    ProcessRecord mProfileProc = null;
1049    String mProfileFile;
1050    ParcelFileDescriptor mProfileFd;
1051    int mSamplingInterval = 0;
1052    boolean mAutoStopProfiler = false;
1053    int mProfileType = 0;
1054    String mOpenGlTraceApp = null;
1055
1056    static class ProcessChangeItem {
1057        static final int CHANGE_ACTIVITIES = 1<<0;
1058        static final int CHANGE_PROCESS_STATE = 1<<1;
1059        int changes;
1060        int uid;
1061        int pid;
1062        int processState;
1063        boolean foregroundActivities;
1064    }
1065
1066    final RemoteCallbackList<IProcessObserver> mProcessObservers
1067            = new RemoteCallbackList<IProcessObserver>();
1068    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1069
1070    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1071            = new ArrayList<ProcessChangeItem>();
1072    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1073            = new ArrayList<ProcessChangeItem>();
1074
1075    /**
1076     * Runtime CPU use collection thread.  This object's lock is used to
1077     * protect all related state.
1078     */
1079    final Thread mProcessCpuThread;
1080
1081    /**
1082     * Used to collect process stats when showing not responding dialog.
1083     * Protected by mProcessCpuThread.
1084     */
1085    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1086            MONITOR_THREAD_CPU_USAGE);
1087    final AtomicLong mLastCpuTime = new AtomicLong(0);
1088    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1089
1090    long mLastWriteTime = 0;
1091
1092    /**
1093     * Used to retain an update lock when the foreground activity is in
1094     * immersive mode.
1095     */
1096    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1097
1098    /**
1099     * Set to true after the system has finished booting.
1100     */
1101    boolean mBooted = false;
1102
1103    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1104    int mProcessLimitOverride = -1;
1105
1106    WindowManagerService mWindowManager;
1107
1108    final ActivityThread mSystemThread;
1109
1110    int mCurrentUserId = 0;
1111    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1112
1113    /**
1114     * Mapping from each known user ID to the profile group ID it is associated with.
1115     */
1116    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1117
1118    private UserManagerService mUserManager;
1119
1120    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1121        final ProcessRecord mApp;
1122        final int mPid;
1123        final IApplicationThread mAppThread;
1124
1125        AppDeathRecipient(ProcessRecord app, int pid,
1126                IApplicationThread thread) {
1127            if (localLOGV) Slog.v(
1128                TAG, "New death recipient " + this
1129                + " for thread " + thread.asBinder());
1130            mApp = app;
1131            mPid = pid;
1132            mAppThread = thread;
1133        }
1134
1135        @Override
1136        public void binderDied() {
1137            if (localLOGV) Slog.v(
1138                TAG, "Death received in " + this
1139                + " for thread " + mAppThread.asBinder());
1140            synchronized(ActivityManagerService.this) {
1141                appDiedLocked(mApp, mPid, mAppThread);
1142            }
1143        }
1144    }
1145
1146    static final int SHOW_ERROR_MSG = 1;
1147    static final int SHOW_NOT_RESPONDING_MSG = 2;
1148    static final int SHOW_FACTORY_ERROR_MSG = 3;
1149    static final int UPDATE_CONFIGURATION_MSG = 4;
1150    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1151    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1152    static final int SERVICE_TIMEOUT_MSG = 12;
1153    static final int UPDATE_TIME_ZONE = 13;
1154    static final int SHOW_UID_ERROR_MSG = 14;
1155    static final int IM_FEELING_LUCKY_MSG = 15;
1156    static final int PROC_START_TIMEOUT_MSG = 20;
1157    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1158    static final int KILL_APPLICATION_MSG = 22;
1159    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1160    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1161    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1162    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1163    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1164    static final int CLEAR_DNS_CACHE_MSG = 28;
1165    static final int UPDATE_HTTP_PROXY_MSG = 29;
1166    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1167    static final int DISPATCH_PROCESSES_CHANGED = 31;
1168    static final int DISPATCH_PROCESS_DIED = 32;
1169    static final int REPORT_MEM_USAGE_MSG = 33;
1170    static final int REPORT_USER_SWITCH_MSG = 34;
1171    static final int CONTINUE_USER_SWITCH_MSG = 35;
1172    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1173    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1174    static final int PERSIST_URI_GRANTS_MSG = 38;
1175    static final int REQUEST_ALL_PSS_MSG = 39;
1176    static final int START_PROFILES_MSG = 40;
1177    static final int UPDATE_TIME = 41;
1178    static final int SYSTEM_USER_START_MSG = 42;
1179    static final int SYSTEM_USER_CURRENT_MSG = 43;
1180    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1181    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1182    static final int START_USER_SWITCH_MSG = 46;
1183
1184    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1185    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1186    static final int FIRST_COMPAT_MODE_MSG = 300;
1187    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1188
1189    AlertDialog mUidAlert;
1190    CompatModeDialog mCompatModeDialog;
1191    long mLastMemUsageReportTime = 0;
1192
1193    private LockToAppRequestDialog mLockToAppRequest;
1194
1195    /**
1196     * Flag whether the current user is a "monkey", i.e. whether
1197     * the UI is driven by a UI automation tool.
1198     */
1199    private boolean mUserIsMonkey;
1200
1201    /** Flag whether the device has a Recents UI */
1202    boolean mHasRecents;
1203
1204    /** The dimensions of the thumbnails in the Recents UI. */
1205    int mThumbnailWidth;
1206    int mThumbnailHeight;
1207
1208    final ServiceThread mHandlerThread;
1209    final MainHandler mHandler;
1210
1211    final class MainHandler extends Handler {
1212        public MainHandler(Looper looper) {
1213            super(looper, null, true);
1214        }
1215
1216        @Override
1217        public void handleMessage(Message msg) {
1218            switch (msg.what) {
1219            case SHOW_ERROR_MSG: {
1220                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1221                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1222                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1223                synchronized (ActivityManagerService.this) {
1224                    ProcessRecord proc = (ProcessRecord)data.get("app");
1225                    AppErrorResult res = (AppErrorResult) data.get("result");
1226                    if (proc != null && proc.crashDialog != null) {
1227                        Slog.e(TAG, "App already has crash dialog: " + proc);
1228                        if (res != null) {
1229                            res.set(0);
1230                        }
1231                        return;
1232                    }
1233                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1234                            >= Process.FIRST_APPLICATION_UID
1235                            && proc.pid != MY_PID);
1236                    for (int userId : mCurrentProfileIds) {
1237                        isBackground &= (proc.userId != userId);
1238                    }
1239                    if (isBackground && !showBackground) {
1240                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1241                        if (res != null) {
1242                            res.set(0);
1243                        }
1244                        return;
1245                    }
1246                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1247                        Dialog d = new AppErrorDialog(mContext,
1248                                ActivityManagerService.this, res, proc);
1249                        d.show();
1250                        proc.crashDialog = d;
1251                    } else {
1252                        // The device is asleep, so just pretend that the user
1253                        // saw a crash dialog and hit "force quit".
1254                        if (res != null) {
1255                            res.set(0);
1256                        }
1257                    }
1258                }
1259
1260                ensureBootCompleted();
1261            } break;
1262            case SHOW_NOT_RESPONDING_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1265                    ProcessRecord proc = (ProcessRecord)data.get("app");
1266                    if (proc != null && proc.anrDialog != null) {
1267                        Slog.e(TAG, "App already has anr dialog: " + proc);
1268                        return;
1269                    }
1270
1271                    Intent intent = new Intent("android.intent.action.ANR");
1272                    if (!mProcessesReady) {
1273                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1274                                | Intent.FLAG_RECEIVER_FOREGROUND);
1275                    }
1276                    broadcastIntentLocked(null, null, intent,
1277                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1278                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1279
1280                    if (mShowDialogs) {
1281                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1282                                mContext, proc, (ActivityRecord)data.get("activity"),
1283                                msg.arg1 != 0);
1284                        d.show();
1285                        proc.anrDialog = d;
1286                    } else {
1287                        // Just kill the app if there is no dialog to be shown.
1288                        killAppAtUsersRequest(proc, null);
1289                    }
1290                }
1291
1292                ensureBootCompleted();
1293            } break;
1294            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1295                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1296                synchronized (ActivityManagerService.this) {
1297                    ProcessRecord proc = (ProcessRecord) data.get("app");
1298                    if (proc == null) {
1299                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1300                        break;
1301                    }
1302                    if (proc.crashDialog != null) {
1303                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1304                        return;
1305                    }
1306                    AppErrorResult res = (AppErrorResult) data.get("result");
1307                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1308                        Dialog d = new StrictModeViolationDialog(mContext,
1309                                ActivityManagerService.this, res, proc);
1310                        d.show();
1311                        proc.crashDialog = d;
1312                    } else {
1313                        // The device is asleep, so just pretend that the user
1314                        // saw a crash dialog and hit "force quit".
1315                        res.set(0);
1316                    }
1317                }
1318                ensureBootCompleted();
1319            } break;
1320            case SHOW_FACTORY_ERROR_MSG: {
1321                Dialog d = new FactoryErrorDialog(
1322                    mContext, msg.getData().getCharSequence("msg"));
1323                d.show();
1324                ensureBootCompleted();
1325            } break;
1326            case UPDATE_CONFIGURATION_MSG: {
1327                final ContentResolver resolver = mContext.getContentResolver();
1328                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1329            } break;
1330            case GC_BACKGROUND_PROCESSES_MSG: {
1331                synchronized (ActivityManagerService.this) {
1332                    performAppGcsIfAppropriateLocked();
1333                }
1334            } break;
1335            case WAIT_FOR_DEBUGGER_MSG: {
1336                synchronized (ActivityManagerService.this) {
1337                    ProcessRecord app = (ProcessRecord)msg.obj;
1338                    if (msg.arg1 != 0) {
1339                        if (!app.waitedForDebugger) {
1340                            Dialog d = new AppWaitingForDebuggerDialog(
1341                                    ActivityManagerService.this,
1342                                    mContext, app);
1343                            app.waitDialog = d;
1344                            app.waitedForDebugger = true;
1345                            d.show();
1346                        }
1347                    } else {
1348                        if (app.waitDialog != null) {
1349                            app.waitDialog.dismiss();
1350                            app.waitDialog = null;
1351                        }
1352                    }
1353                }
1354            } break;
1355            case SERVICE_TIMEOUT_MSG: {
1356                if (mDidDexOpt) {
1357                    mDidDexOpt = false;
1358                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1359                    nmsg.obj = msg.obj;
1360                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1361                    return;
1362                }
1363                mServices.serviceTimeout((ProcessRecord)msg.obj);
1364            } break;
1365            case UPDATE_TIME_ZONE: {
1366                synchronized (ActivityManagerService.this) {
1367                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1368                        ProcessRecord r = mLruProcesses.get(i);
1369                        if (r.thread != null) {
1370                            try {
1371                                r.thread.updateTimeZone();
1372                            } catch (RemoteException ex) {
1373                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1374                            }
1375                        }
1376                    }
1377                }
1378            } break;
1379            case CLEAR_DNS_CACHE_MSG: {
1380                synchronized (ActivityManagerService.this) {
1381                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1382                        ProcessRecord r = mLruProcesses.get(i);
1383                        if (r.thread != null) {
1384                            try {
1385                                r.thread.clearDnsCache();
1386                            } catch (RemoteException ex) {
1387                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1388                            }
1389                        }
1390                    }
1391                }
1392            } break;
1393            case UPDATE_HTTP_PROXY_MSG: {
1394                ProxyInfo proxy = (ProxyInfo)msg.obj;
1395                String host = "";
1396                String port = "";
1397                String exclList = "";
1398                Uri pacFileUrl = Uri.EMPTY;
1399                if (proxy != null) {
1400                    host = proxy.getHost();
1401                    port = Integer.toString(proxy.getPort());
1402                    exclList = proxy.getExclusionListAsString();
1403                    pacFileUrl = proxy.getPacFileUrl();
1404                }
1405                synchronized (ActivityManagerService.this) {
1406                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1407                        ProcessRecord r = mLruProcesses.get(i);
1408                        if (r.thread != null) {
1409                            try {
1410                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1411                            } catch (RemoteException ex) {
1412                                Slog.w(TAG, "Failed to update http proxy for: " +
1413                                        r.info.processName);
1414                            }
1415                        }
1416                    }
1417                }
1418            } break;
1419            case SHOW_UID_ERROR_MSG: {
1420                String title = "System UIDs Inconsistent";
1421                String text = "UIDs on the system are inconsistent, you need to wipe your"
1422                        + " data partition or your device will be unstable.";
1423                Log.e(TAG, title + ": " + text);
1424                if (mShowDialogs) {
1425                    // XXX This is a temporary dialog, no need to localize.
1426                    AlertDialog d = new BaseErrorDialog(mContext);
1427                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1428                    d.setCancelable(false);
1429                    d.setTitle(title);
1430                    d.setMessage(text);
1431                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1432                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1433                    mUidAlert = d;
1434                    d.show();
1435                }
1436            } break;
1437            case IM_FEELING_LUCKY_MSG: {
1438                if (mUidAlert != null) {
1439                    mUidAlert.dismiss();
1440                    mUidAlert = null;
1441                }
1442            } break;
1443            case PROC_START_TIMEOUT_MSG: {
1444                if (mDidDexOpt) {
1445                    mDidDexOpt = false;
1446                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1447                    nmsg.obj = msg.obj;
1448                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1449                    return;
1450                }
1451                ProcessRecord app = (ProcessRecord)msg.obj;
1452                synchronized (ActivityManagerService.this) {
1453                    processStartTimedOutLocked(app);
1454                }
1455            } break;
1456            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1457                synchronized (ActivityManagerService.this) {
1458                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1459                }
1460            } break;
1461            case KILL_APPLICATION_MSG: {
1462                synchronized (ActivityManagerService.this) {
1463                    int appid = msg.arg1;
1464                    boolean restart = (msg.arg2 == 1);
1465                    Bundle bundle = (Bundle)msg.obj;
1466                    String pkg = bundle.getString("pkg");
1467                    String reason = bundle.getString("reason");
1468                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1469                            false, UserHandle.USER_ALL, reason);
1470                }
1471            } break;
1472            case FINALIZE_PENDING_INTENT_MSG: {
1473                ((PendingIntentRecord)msg.obj).completeFinalize();
1474            } break;
1475            case POST_HEAVY_NOTIFICATION_MSG: {
1476                INotificationManager inm = NotificationManager.getService();
1477                if (inm == null) {
1478                    return;
1479                }
1480
1481                ActivityRecord root = (ActivityRecord)msg.obj;
1482                ProcessRecord process = root.app;
1483                if (process == null) {
1484                    return;
1485                }
1486
1487                try {
1488                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1489                    String text = mContext.getString(R.string.heavy_weight_notification,
1490                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1491                    Notification notification = new Notification();
1492                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1493                    notification.when = 0;
1494                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1495                    notification.tickerText = text;
1496                    notification.defaults = 0; // please be quiet
1497                    notification.sound = null;
1498                    notification.vibrate = null;
1499                    notification.color = mContext.getResources().getColor(
1500                            com.android.internal.R.color.system_notification_accent_color);
1501                    notification.setLatestEventInfo(context, text,
1502                            mContext.getText(R.string.heavy_weight_notification_detail),
1503                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1504                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1505                                    new UserHandle(root.userId)));
1506
1507                    try {
1508                        int[] outId = new int[1];
1509                        inm.enqueueNotificationWithTag("android", "android", null,
1510                                R.string.heavy_weight_notification,
1511                                notification, outId, root.userId);
1512                    } catch (RuntimeException e) {
1513                        Slog.w(ActivityManagerService.TAG,
1514                                "Error showing notification for heavy-weight app", e);
1515                    } catch (RemoteException e) {
1516                    }
1517                } catch (NameNotFoundException e) {
1518                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1519                }
1520            } break;
1521            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1522                INotificationManager inm = NotificationManager.getService();
1523                if (inm == null) {
1524                    return;
1525                }
1526                try {
1527                    inm.cancelNotificationWithTag("android", null,
1528                            R.string.heavy_weight_notification,  msg.arg1);
1529                } catch (RuntimeException e) {
1530                    Slog.w(ActivityManagerService.TAG,
1531                            "Error canceling notification for service", e);
1532                } catch (RemoteException e) {
1533                }
1534            } break;
1535            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1536                synchronized (ActivityManagerService.this) {
1537                    checkExcessivePowerUsageLocked(true);
1538                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1539                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1540                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1541                }
1542            } break;
1543            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    ActivityRecord ar = (ActivityRecord)msg.obj;
1546                    if (mCompatModeDialog != null) {
1547                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1548                                ar.info.applicationInfo.packageName)) {
1549                            return;
1550                        }
1551                        mCompatModeDialog.dismiss();
1552                        mCompatModeDialog = null;
1553                    }
1554                    if (ar != null && false) {
1555                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1556                                ar.packageName)) {
1557                            int mode = mCompatModePackages.computeCompatModeLocked(
1558                                    ar.info.applicationInfo);
1559                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1560                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1561                                mCompatModeDialog = new CompatModeDialog(
1562                                        ActivityManagerService.this, mContext,
1563                                        ar.info.applicationInfo);
1564                                mCompatModeDialog.show();
1565                            }
1566                        }
1567                    }
1568                }
1569                break;
1570            }
1571            case DISPATCH_PROCESSES_CHANGED: {
1572                dispatchProcessesChanged();
1573                break;
1574            }
1575            case DISPATCH_PROCESS_DIED: {
1576                final int pid = msg.arg1;
1577                final int uid = msg.arg2;
1578                dispatchProcessDied(pid, uid);
1579                break;
1580            }
1581            case REPORT_MEM_USAGE_MSG: {
1582                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1583                Thread thread = new Thread() {
1584                    @Override public void run() {
1585                        final SparseArray<ProcessMemInfo> infoMap
1586                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589                            infoMap.put(mi.pid, mi);
1590                        }
1591                        updateCpuStatsNow();
1592                        synchronized (mProcessCpuThread) {
1593                            final int N = mProcessCpuTracker.countStats();
1594                            for (int i=0; i<N; i++) {
1595                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1596                                if (st.vsize > 0) {
1597                                    long pss = Debug.getPss(st.pid, null);
1598                                    if (pss > 0) {
1599                                        if (infoMap.indexOfKey(st.pid) < 0) {
1600                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1601                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1602                                            mi.pss = pss;
1603                                            memInfos.add(mi);
1604                                        }
1605                                    }
1606                                }
1607                            }
1608                        }
1609
1610                        long totalPss = 0;
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613                            if (mi.pss == 0) {
1614                                mi.pss = Debug.getPss(mi.pid, null);
1615                            }
1616                            totalPss += mi.pss;
1617                        }
1618                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1619                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1620                                if (lhs.oomAdj != rhs.oomAdj) {
1621                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1622                                }
1623                                if (lhs.pss != rhs.pss) {
1624                                    return lhs.pss < rhs.pss ? 1 : -1;
1625                                }
1626                                return 0;
1627                            }
1628                        });
1629
1630                        StringBuilder tag = new StringBuilder(128);
1631                        StringBuilder stack = new StringBuilder(128);
1632                        tag.append("Low on memory -- ");
1633                        appendMemBucket(tag, totalPss, "total", false);
1634                        appendMemBucket(stack, totalPss, "total", true);
1635
1636                        StringBuilder logBuilder = new StringBuilder(1024);
1637                        logBuilder.append("Low on memory:\n");
1638
1639                        boolean firstLine = true;
1640                        int lastOomAdj = Integer.MIN_VALUE;
1641                        for (int i=0, N=memInfos.size(); i<N; i++) {
1642                            ProcessMemInfo mi = memInfos.get(i);
1643
1644                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1645                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1646                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1647                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1648                                if (lastOomAdj != mi.oomAdj) {
1649                                    lastOomAdj = mi.oomAdj;
1650                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1651                                        tag.append(" / ");
1652                                    }
1653                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1654                                        if (firstLine) {
1655                                            stack.append(":");
1656                                            firstLine = false;
1657                                        }
1658                                        stack.append("\n\t at ");
1659                                    } else {
1660                                        stack.append("$");
1661                                    }
1662                                } else {
1663                                    tag.append(" ");
1664                                    stack.append("$");
1665                                }
1666                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1667                                    appendMemBucket(tag, mi.pss, mi.name, false);
1668                                }
1669                                appendMemBucket(stack, mi.pss, mi.name, true);
1670                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1671                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1672                                    stack.append("(");
1673                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1674                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1675                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1676                                            stack.append(":");
1677                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1678                                        }
1679                                    }
1680                                    stack.append(")");
1681                                }
1682                            }
1683
1684                            logBuilder.append("  ");
1685                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1686                            logBuilder.append(' ');
1687                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1688                            logBuilder.append(' ');
1689                            ProcessList.appendRamKb(logBuilder, mi.pss);
1690                            logBuilder.append(" kB: ");
1691                            logBuilder.append(mi.name);
1692                            logBuilder.append(" (");
1693                            logBuilder.append(mi.pid);
1694                            logBuilder.append(") ");
1695                            logBuilder.append(mi.adjType);
1696                            logBuilder.append('\n');
1697                            if (mi.adjReason != null) {
1698                                logBuilder.append("                      ");
1699                                logBuilder.append(mi.adjReason);
1700                                logBuilder.append('\n');
1701                            }
1702                        }
1703
1704                        logBuilder.append("           ");
1705                        ProcessList.appendRamKb(logBuilder, totalPss);
1706                        logBuilder.append(" kB: TOTAL\n");
1707
1708                        long[] infos = new long[Debug.MEMINFO_COUNT];
1709                        Debug.getMemInfo(infos);
1710                        logBuilder.append("  MemInfo: ");
1711                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1713                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1714                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1715                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1716                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1717                            logBuilder.append("  ZRAM: ");
1718                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1719                            logBuilder.append(" kB RAM, ");
1720                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1721                            logBuilder.append(" kB swap total, ");
1722                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1723                            logBuilder.append(" kB swap free\n");
1724                        }
1725                        Slog.i(TAG, logBuilder.toString());
1726
1727                        StringBuilder dropBuilder = new StringBuilder(1024);
1728                        /*
1729                        StringWriter oomSw = new StringWriter();
1730                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1731                        StringWriter catSw = new StringWriter();
1732                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1733                        String[] emptyArgs = new String[] { };
1734                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1735                        oomPw.flush();
1736                        String oomString = oomSw.toString();
1737                        */
1738                        dropBuilder.append(stack);
1739                        dropBuilder.append('\n');
1740                        dropBuilder.append('\n');
1741                        dropBuilder.append(logBuilder);
1742                        dropBuilder.append('\n');
1743                        /*
1744                        dropBuilder.append(oomString);
1745                        dropBuilder.append('\n');
1746                        */
1747                        StringWriter catSw = new StringWriter();
1748                        synchronized (ActivityManagerService.this) {
1749                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1750                            String[] emptyArgs = new String[] { };
1751                            catPw.println();
1752                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1753                            catPw.println();
1754                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1755                                    false, false, null);
1756                            catPw.println();
1757                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1758                            catPw.flush();
1759                        }
1760                        dropBuilder.append(catSw.toString());
1761                        addErrorToDropBox("lowmem", null, "system_server", null,
1762                                null, tag.toString(), dropBuilder.toString(), null, null);
1763                        //Slog.i(TAG, "Sent to dropbox:");
1764                        //Slog.i(TAG, dropBuilder.toString());
1765                        synchronized (ActivityManagerService.this) {
1766                            long now = SystemClock.uptimeMillis();
1767                            if (mLastMemUsageReportTime < now) {
1768                                mLastMemUsageReportTime = now;
1769                            }
1770                        }
1771                    }
1772                };
1773                thread.start();
1774                break;
1775            }
1776            case START_USER_SWITCH_MSG: {
1777                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1778                break;
1779            }
1780            case REPORT_USER_SWITCH_MSG: {
1781                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1782                break;
1783            }
1784            case CONTINUE_USER_SWITCH_MSG: {
1785                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1786                break;
1787            }
1788            case USER_SWITCH_TIMEOUT_MSG: {
1789                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1790                break;
1791            }
1792            case IMMERSIVE_MODE_LOCK_MSG: {
1793                final boolean nextState = (msg.arg1 != 0);
1794                if (mUpdateLock.isHeld() != nextState) {
1795                    if (DEBUG_IMMERSIVE) {
1796                        final ActivityRecord r = (ActivityRecord) msg.obj;
1797                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1798                    }
1799                    if (nextState) {
1800                        mUpdateLock.acquire();
1801                    } else {
1802                        mUpdateLock.release();
1803                    }
1804                }
1805                break;
1806            }
1807            case PERSIST_URI_GRANTS_MSG: {
1808                writeGrantedUriPermissions();
1809                break;
1810            }
1811            case REQUEST_ALL_PSS_MSG: {
1812                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1813                break;
1814            }
1815            case START_PROFILES_MSG: {
1816                synchronized (ActivityManagerService.this) {
1817                    startProfilesLocked();
1818                }
1819                break;
1820            }
1821            case UPDATE_TIME: {
1822                synchronized (ActivityManagerService.this) {
1823                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1824                        ProcessRecord r = mLruProcesses.get(i);
1825                        if (r.thread != null) {
1826                            try {
1827                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1828                            } catch (RemoteException ex) {
1829                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1830                            }
1831                        }
1832                    }
1833                }
1834                break;
1835            }
1836            case SYSTEM_USER_START_MSG: {
1837                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1838                        Integer.toString(msg.arg1), msg.arg1);
1839                mSystemServiceManager.startUser(msg.arg1);
1840                break;
1841            }
1842            case SYSTEM_USER_CURRENT_MSG: {
1843                mBatteryStatsService.noteEvent(
1844                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1845                        Integer.toString(msg.arg2), msg.arg2);
1846                mBatteryStatsService.noteEvent(
1847                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1848                        Integer.toString(msg.arg1), msg.arg1);
1849                mSystemServiceManager.switchUser(msg.arg1);
1850                mLockToAppRequest.clearPrompt();
1851                break;
1852            }
1853            case ENTER_ANIMATION_COMPLETE_MSG: {
1854                synchronized (ActivityManagerService.this) {
1855                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1856                    if (r != null && r.app != null && r.app.thread != null) {
1857                        try {
1858                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1859                        } catch (RemoteException e) {
1860                        }
1861                    }
1862                }
1863                break;
1864            }
1865            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1866                enableScreenAfterBoot();
1867                break;
1868            }
1869            }
1870        }
1871    };
1872
1873    static final int COLLECT_PSS_BG_MSG = 1;
1874
1875    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1876        @Override
1877        public void handleMessage(Message msg) {
1878            switch (msg.what) {
1879            case COLLECT_PSS_BG_MSG: {
1880                long start = SystemClock.uptimeMillis();
1881                MemInfoReader memInfo = null;
1882                synchronized (ActivityManagerService.this) {
1883                    if (mFullPssPending) {
1884                        mFullPssPending = false;
1885                        memInfo = new MemInfoReader();
1886                    }
1887                }
1888                if (memInfo != null) {
1889                    updateCpuStatsNow();
1890                    long nativeTotalPss = 0;
1891                    synchronized (mProcessCpuThread) {
1892                        final int N = mProcessCpuTracker.countStats();
1893                        for (int j=0; j<N; j++) {
1894                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1895                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1896                                // This is definitely an application process; skip it.
1897                                continue;
1898                            }
1899                            synchronized (mPidsSelfLocked) {
1900                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1901                                    // This is one of our own processes; skip it.
1902                                    continue;
1903                                }
1904                            }
1905                            nativeTotalPss += Debug.getPss(st.pid, null);
1906                        }
1907                    }
1908                    memInfo.readMemInfo();
1909                    synchronized (this) {
1910                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1911                                + (SystemClock.uptimeMillis()-start) + "ms");
1912                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1913                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1914                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1915                                        +memInfo.getSlabSizeKb(),
1916                                nativeTotalPss);
1917                    }
1918                }
1919
1920                int i=0, num=0;
1921                long[] tmp = new long[1];
1922                do {
1923                    ProcessRecord proc;
1924                    int procState;
1925                    int pid;
1926                    synchronized (ActivityManagerService.this) {
1927                        if (i >= mPendingPssProcesses.size()) {
1928                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1929                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1930                            mPendingPssProcesses.clear();
1931                            return;
1932                        }
1933                        proc = mPendingPssProcesses.get(i);
1934                        procState = proc.pssProcState;
1935                        if (proc.thread != null && procState == proc.setProcState) {
1936                            pid = proc.pid;
1937                        } else {
1938                            proc = null;
1939                            pid = 0;
1940                        }
1941                        i++;
1942                    }
1943                    if (proc != null) {
1944                        long pss = Debug.getPss(pid, tmp);
1945                        synchronized (ActivityManagerService.this) {
1946                            if (proc.thread != null && proc.setProcState == procState
1947                                    && proc.pid == pid) {
1948                                num++;
1949                                proc.lastPssTime = SystemClock.uptimeMillis();
1950                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1951                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1952                                        + ": " + pss + " lastPss=" + proc.lastPss
1953                                        + " state=" + ProcessList.makeProcStateString(procState));
1954                                if (proc.initialIdlePss == 0) {
1955                                    proc.initialIdlePss = pss;
1956                                }
1957                                proc.lastPss = pss;
1958                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1959                                    proc.lastCachedPss = pss;
1960                                }
1961                            }
1962                        }
1963                    }
1964                } while (true);
1965            }
1966            }
1967        }
1968    };
1969
1970    /**
1971     * Monitor for package changes and update our internal state.
1972     */
1973    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1974        @Override
1975        public void onPackageRemoved(String packageName, int uid) {
1976            // Remove all tasks with activities in the specified package from the list of recent tasks
1977            synchronized (ActivityManagerService.this) {
1978                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1979                    TaskRecord tr = mRecentTasks.get(i);
1980                    ComponentName cn = tr.intent.getComponent();
1981                    if (cn != null && cn.getPackageName().equals(packageName)) {
1982                        // If the package name matches, remove the task and kill the process
1983                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1984                    }
1985                }
1986            }
1987        }
1988
1989        @Override
1990        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1991            onPackageModified(packageName);
1992            return true;
1993        }
1994
1995        @Override
1996        public void onPackageModified(String packageName) {
1997            final PackageManager pm = mContext.getPackageManager();
1998            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1999                    new ArrayList<Pair<Intent, Integer>>();
2000            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2001            // Copy the list of recent tasks so that we don't hold onto the lock on
2002            // ActivityManagerService for long periods while checking if components exist.
2003            synchronized (ActivityManagerService.this) {
2004                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2005                    TaskRecord tr = mRecentTasks.get(i);
2006                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2007                }
2008            }
2009            // Check the recent tasks and filter out all tasks with components that no longer exist.
2010            Intent tmpI = new Intent();
2011            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2012                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2013                ComponentName cn = p.first.getComponent();
2014                if (cn != null && cn.getPackageName().equals(packageName)) {
2015                    try {
2016                        // Add the task to the list to remove if the component no longer exists
2017                        tmpI.setComponent(cn);
2018                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2019                            tasksToRemove.add(p.second);
2020                        }
2021                    } catch (Exception e) {}
2022                }
2023            }
2024            // Prune all the tasks with removed components from the list of recent tasks
2025            synchronized (ActivityManagerService.this) {
2026                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2027                    // Remove the task but don't kill the process (since other components in that
2028                    // package may still be running and in the background)
2029                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2030                }
2031            }
2032        }
2033
2034        @Override
2035        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2036            // Force stop the specified packages
2037            if (packages != null) {
2038                for (String pkg : packages) {
2039                    synchronized (ActivityManagerService.this) {
2040                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2041                                "finished booting")) {
2042                            return true;
2043                        }
2044                    }
2045                }
2046            }
2047            return false;
2048        }
2049    };
2050
2051    public void setSystemProcess() {
2052        try {
2053            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2054            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2055            ServiceManager.addService("meminfo", new MemBinder(this));
2056            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2057            ServiceManager.addService("dbinfo", new DbBinder(this));
2058            if (MONITOR_CPU_USAGE) {
2059                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2060            }
2061            ServiceManager.addService("permission", new PermissionController(this));
2062
2063            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2064                    "android", STOCK_PM_FLAGS);
2065            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2066
2067            synchronized (this) {
2068                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2069                app.persistent = true;
2070                app.pid = MY_PID;
2071                app.maxAdj = ProcessList.SYSTEM_ADJ;
2072                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2073                mProcessNames.put(app.processName, app.uid, app);
2074                synchronized (mPidsSelfLocked) {
2075                    mPidsSelfLocked.put(app.pid, app);
2076                }
2077                updateLruProcessLocked(app, false, null);
2078                updateOomAdjLocked();
2079            }
2080        } catch (PackageManager.NameNotFoundException e) {
2081            throw new RuntimeException(
2082                    "Unable to find android system package", e);
2083        }
2084    }
2085
2086    public void setWindowManager(WindowManagerService wm) {
2087        mWindowManager = wm;
2088        mStackSupervisor.setWindowManager(wm);
2089    }
2090
2091    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2092        mUsageStatsService = usageStatsManager;
2093    }
2094
2095    public void startObservingNativeCrashes() {
2096        final NativeCrashListener ncl = new NativeCrashListener(this);
2097        ncl.start();
2098    }
2099
2100    public IAppOpsService getAppOpsService() {
2101        return mAppOpsService;
2102    }
2103
2104    static class MemBinder extends Binder {
2105        ActivityManagerService mActivityManagerService;
2106        MemBinder(ActivityManagerService activityManagerService) {
2107            mActivityManagerService = activityManagerService;
2108        }
2109
2110        @Override
2111        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2112            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2113                    != PackageManager.PERMISSION_GRANTED) {
2114                pw.println("Permission Denial: can't dump meminfo from from pid="
2115                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2116                        + " without permission " + android.Manifest.permission.DUMP);
2117                return;
2118            }
2119
2120            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2121        }
2122    }
2123
2124    static class GraphicsBinder extends Binder {
2125        ActivityManagerService mActivityManagerService;
2126        GraphicsBinder(ActivityManagerService activityManagerService) {
2127            mActivityManagerService = activityManagerService;
2128        }
2129
2130        @Override
2131        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2132            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2133                    != PackageManager.PERMISSION_GRANTED) {
2134                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2135                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2136                        + " without permission " + android.Manifest.permission.DUMP);
2137                return;
2138            }
2139
2140            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2141        }
2142    }
2143
2144    static class DbBinder extends Binder {
2145        ActivityManagerService mActivityManagerService;
2146        DbBinder(ActivityManagerService activityManagerService) {
2147            mActivityManagerService = activityManagerService;
2148        }
2149
2150        @Override
2151        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2152            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2153                    != PackageManager.PERMISSION_GRANTED) {
2154                pw.println("Permission Denial: can't dump dbinfo from from pid="
2155                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2156                        + " without permission " + android.Manifest.permission.DUMP);
2157                return;
2158            }
2159
2160            mActivityManagerService.dumpDbInfo(fd, pw, args);
2161        }
2162    }
2163
2164    static class CpuBinder extends Binder {
2165        ActivityManagerService mActivityManagerService;
2166        CpuBinder(ActivityManagerService activityManagerService) {
2167            mActivityManagerService = activityManagerService;
2168        }
2169
2170        @Override
2171        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2172            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2173                    != PackageManager.PERMISSION_GRANTED) {
2174                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2175                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2176                        + " without permission " + android.Manifest.permission.DUMP);
2177                return;
2178            }
2179
2180            synchronized (mActivityManagerService.mProcessCpuThread) {
2181                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2182                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2183                        SystemClock.uptimeMillis()));
2184            }
2185        }
2186    }
2187
2188    public static final class Lifecycle extends SystemService {
2189        private final ActivityManagerService mService;
2190
2191        public Lifecycle(Context context) {
2192            super(context);
2193            mService = new ActivityManagerService(context);
2194        }
2195
2196        @Override
2197        public void onStart() {
2198            mService.start();
2199        }
2200
2201        public ActivityManagerService getService() {
2202            return mService;
2203        }
2204    }
2205
2206    // Note: This method is invoked on the main thread but may need to attach various
2207    // handlers to other threads.  So take care to be explicit about the looper.
2208    public ActivityManagerService(Context systemContext) {
2209        mContext = systemContext;
2210        mFactoryTest = FactoryTest.getMode();
2211        mSystemThread = ActivityThread.currentActivityThread();
2212
2213        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2214
2215        mHandlerThread = new ServiceThread(TAG,
2216                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2217        mHandlerThread.start();
2218        mHandler = new MainHandler(mHandlerThread.getLooper());
2219
2220        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2221                "foreground", BROADCAST_FG_TIMEOUT, false);
2222        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2223                "background", BROADCAST_BG_TIMEOUT, true);
2224        mBroadcastQueues[0] = mFgBroadcastQueue;
2225        mBroadcastQueues[1] = mBgBroadcastQueue;
2226
2227        mServices = new ActiveServices(this);
2228        mProviderMap = new ProviderMap(this);
2229
2230        // TODO: Move creation of battery stats service outside of activity manager service.
2231        File dataDir = Environment.getDataDirectory();
2232        File systemDir = new File(dataDir, "system");
2233        systemDir.mkdirs();
2234        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2235        mBatteryStatsService.getActiveStatistics().readLocked();
2236        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2237        mOnBattery = DEBUG_POWER ? true
2238                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2239        mBatteryStatsService.getActiveStatistics().setCallback(this);
2240
2241        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2242
2243        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2244
2245        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2246
2247        // User 0 is the first and only user that runs at boot.
2248        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2249        mUserLru.add(Integer.valueOf(0));
2250        updateStartedUserArrayLocked();
2251
2252        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2253            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2254
2255        mConfiguration.setToDefaults();
2256        mConfiguration.setLocale(Locale.getDefault());
2257
2258        mConfigurationSeq = mConfiguration.seq = 1;
2259        mProcessCpuTracker.init();
2260
2261        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2262        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2263        mStackSupervisor = new ActivityStackSupervisor(this);
2264        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2265
2266        mProcessCpuThread = new Thread("CpuTracker") {
2267            @Override
2268            public void run() {
2269                while (true) {
2270                    try {
2271                        try {
2272                            synchronized(this) {
2273                                final long now = SystemClock.uptimeMillis();
2274                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2275                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2276                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2277                                //        + ", write delay=" + nextWriteDelay);
2278                                if (nextWriteDelay < nextCpuDelay) {
2279                                    nextCpuDelay = nextWriteDelay;
2280                                }
2281                                if (nextCpuDelay > 0) {
2282                                    mProcessCpuMutexFree.set(true);
2283                                    this.wait(nextCpuDelay);
2284                                }
2285                            }
2286                        } catch (InterruptedException e) {
2287                        }
2288                        updateCpuStatsNow();
2289                    } catch (Exception e) {
2290                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2291                    }
2292                }
2293            }
2294        };
2295
2296        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2297
2298        Watchdog.getInstance().addMonitor(this);
2299        Watchdog.getInstance().addThread(mHandler);
2300    }
2301
2302    public void setSystemServiceManager(SystemServiceManager mgr) {
2303        mSystemServiceManager = mgr;
2304    }
2305
2306    private void start() {
2307        Process.removeAllProcessGroups();
2308        mProcessCpuThread.start();
2309
2310        mBatteryStatsService.publish(mContext);
2311        mAppOpsService.publish(mContext);
2312        Slog.d("AppOps", "AppOpsService published");
2313        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2314    }
2315
2316    public void initPowerManagement() {
2317        mStackSupervisor.initPowerManagement();
2318        mBatteryStatsService.initPowerManagement();
2319    }
2320
2321    @Override
2322    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2323            throws RemoteException {
2324        if (code == SYSPROPS_TRANSACTION) {
2325            // We need to tell all apps about the system property change.
2326            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2327            synchronized(this) {
2328                final int NP = mProcessNames.getMap().size();
2329                for (int ip=0; ip<NP; ip++) {
2330                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2331                    final int NA = apps.size();
2332                    for (int ia=0; ia<NA; ia++) {
2333                        ProcessRecord app = apps.valueAt(ia);
2334                        if (app.thread != null) {
2335                            procs.add(app.thread.asBinder());
2336                        }
2337                    }
2338                }
2339            }
2340
2341            int N = procs.size();
2342            for (int i=0; i<N; i++) {
2343                Parcel data2 = Parcel.obtain();
2344                try {
2345                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2346                } catch (RemoteException e) {
2347                }
2348                data2.recycle();
2349            }
2350        }
2351        try {
2352            return super.onTransact(code, data, reply, flags);
2353        } catch (RuntimeException e) {
2354            // The activity manager only throws security exceptions, so let's
2355            // log all others.
2356            if (!(e instanceof SecurityException)) {
2357                Slog.wtf(TAG, "Activity Manager Crash", e);
2358            }
2359            throw e;
2360        }
2361    }
2362
2363    void updateCpuStats() {
2364        final long now = SystemClock.uptimeMillis();
2365        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2366            return;
2367        }
2368        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2369            synchronized (mProcessCpuThread) {
2370                mProcessCpuThread.notify();
2371            }
2372        }
2373    }
2374
2375    void updateCpuStatsNow() {
2376        synchronized (mProcessCpuThread) {
2377            mProcessCpuMutexFree.set(false);
2378            final long now = SystemClock.uptimeMillis();
2379            boolean haveNewCpuStats = false;
2380
2381            if (MONITOR_CPU_USAGE &&
2382                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2383                mLastCpuTime.set(now);
2384                haveNewCpuStats = true;
2385                mProcessCpuTracker.update();
2386                //Slog.i(TAG, mProcessCpu.printCurrentState());
2387                //Slog.i(TAG, "Total CPU usage: "
2388                //        + mProcessCpu.getTotalCpuPercent() + "%");
2389
2390                // Slog the cpu usage if the property is set.
2391                if ("true".equals(SystemProperties.get("events.cpu"))) {
2392                    int user = mProcessCpuTracker.getLastUserTime();
2393                    int system = mProcessCpuTracker.getLastSystemTime();
2394                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2395                    int irq = mProcessCpuTracker.getLastIrqTime();
2396                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2397                    int idle = mProcessCpuTracker.getLastIdleTime();
2398
2399                    int total = user + system + iowait + irq + softIrq + idle;
2400                    if (total == 0) total = 1;
2401
2402                    EventLog.writeEvent(EventLogTags.CPU,
2403                            ((user+system+iowait+irq+softIrq) * 100) / total,
2404                            (user * 100) / total,
2405                            (system * 100) / total,
2406                            (iowait * 100) / total,
2407                            (irq * 100) / total,
2408                            (softIrq * 100) / total);
2409                }
2410            }
2411
2412            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2413            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2414            synchronized(bstats) {
2415                synchronized(mPidsSelfLocked) {
2416                    if (haveNewCpuStats) {
2417                        if (mOnBattery) {
2418                            int perc = bstats.startAddingCpuLocked();
2419                            int totalUTime = 0;
2420                            int totalSTime = 0;
2421                            final int N = mProcessCpuTracker.countStats();
2422                            for (int i=0; i<N; i++) {
2423                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2424                                if (!st.working) {
2425                                    continue;
2426                                }
2427                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2428                                int otherUTime = (st.rel_utime*perc)/100;
2429                                int otherSTime = (st.rel_stime*perc)/100;
2430                                totalUTime += otherUTime;
2431                                totalSTime += otherSTime;
2432                                if (pr != null) {
2433                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2434                                    if (ps == null || !ps.isActive()) {
2435                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2436                                                pr.info.uid, pr.processName);
2437                                    }
2438                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2439                                            st.rel_stime-otherSTime);
2440                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2441                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2442                                } else {
2443                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2444                                    if (ps == null || !ps.isActive()) {
2445                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2446                                                bstats.mapUid(st.uid), st.name);
2447                                    }
2448                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2449                                            st.rel_stime-otherSTime);
2450                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2451                                }
2452                            }
2453                            bstats.finishAddingCpuLocked(perc, totalUTime,
2454                                    totalSTime, cpuSpeedTimes);
2455                        }
2456                    }
2457                }
2458
2459                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2460                    mLastWriteTime = now;
2461                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2462                }
2463            }
2464        }
2465    }
2466
2467    @Override
2468    public void batteryNeedsCpuUpdate() {
2469        updateCpuStatsNow();
2470    }
2471
2472    @Override
2473    public void batteryPowerChanged(boolean onBattery) {
2474        // When plugging in, update the CPU stats first before changing
2475        // the plug state.
2476        updateCpuStatsNow();
2477        synchronized (this) {
2478            synchronized(mPidsSelfLocked) {
2479                mOnBattery = DEBUG_POWER ? true : onBattery;
2480            }
2481        }
2482    }
2483
2484    /**
2485     * Initialize the application bind args. These are passed to each
2486     * process when the bindApplication() IPC is sent to the process. They're
2487     * lazily setup to make sure the services are running when they're asked for.
2488     */
2489    private HashMap<String, IBinder> getCommonServicesLocked() {
2490        if (mAppBindArgs == null) {
2491            mAppBindArgs = new HashMap<String, IBinder>();
2492
2493            // Setup the application init args
2494            mAppBindArgs.put("package", ServiceManager.getService("package"));
2495            mAppBindArgs.put("window", ServiceManager.getService("window"));
2496            mAppBindArgs.put(Context.ALARM_SERVICE,
2497                    ServiceManager.getService(Context.ALARM_SERVICE));
2498        }
2499        return mAppBindArgs;
2500    }
2501
2502    final void setFocusedActivityLocked(ActivityRecord r) {
2503        if (mFocusedActivity != r) {
2504            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2505            mFocusedActivity = r;
2506            if (r.task != null && r.task.voiceInteractor != null) {
2507                startRunningVoiceLocked();
2508            } else {
2509                finishRunningVoiceLocked();
2510            }
2511            mStackSupervisor.setFocusedStack(r);
2512            if (r != null) {
2513                mWindowManager.setFocusedApp(r.appToken, true);
2514            }
2515            applyUpdateLockStateLocked(r);
2516        }
2517    }
2518
2519    final void clearFocusedActivity(ActivityRecord r) {
2520        if (mFocusedActivity == r) {
2521            mFocusedActivity = null;
2522        }
2523    }
2524
2525    @Override
2526    public void setFocusedStack(int stackId) {
2527        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2528        synchronized (ActivityManagerService.this) {
2529            ActivityStack stack = mStackSupervisor.getStack(stackId);
2530            if (stack != null) {
2531                ActivityRecord r = stack.topRunningActivityLocked(null);
2532                if (r != null) {
2533                    setFocusedActivityLocked(r);
2534                }
2535            }
2536        }
2537    }
2538
2539    @Override
2540    public void notifyActivityDrawn(IBinder token) {
2541        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2542        synchronized (this) {
2543            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2544            if (r != null) {
2545                r.task.stack.notifyActivityDrawnLocked(r);
2546            }
2547        }
2548    }
2549
2550    final void applyUpdateLockStateLocked(ActivityRecord r) {
2551        // Modifications to the UpdateLock state are done on our handler, outside
2552        // the activity manager's locks.  The new state is determined based on the
2553        // state *now* of the relevant activity record.  The object is passed to
2554        // the handler solely for logging detail, not to be consulted/modified.
2555        final boolean nextState = r != null && r.immersive;
2556        mHandler.sendMessage(
2557                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2558    }
2559
2560    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2561        Message msg = Message.obtain();
2562        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2563        msg.obj = r.task.askedCompatMode ? null : r;
2564        mHandler.sendMessage(msg);
2565    }
2566
2567    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2568            String what, Object obj, ProcessRecord srcApp) {
2569        app.lastActivityTime = now;
2570
2571        if (app.activities.size() > 0) {
2572            // Don't want to touch dependent processes that are hosting activities.
2573            return index;
2574        }
2575
2576        int lrui = mLruProcesses.lastIndexOf(app);
2577        if (lrui < 0) {
2578            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2579                    + what + " " + obj + " from " + srcApp);
2580            return index;
2581        }
2582
2583        if (lrui >= index) {
2584            // Don't want to cause this to move dependent processes *back* in the
2585            // list as if they were less frequently used.
2586            return index;
2587        }
2588
2589        if (lrui >= mLruProcessActivityStart) {
2590            // Don't want to touch dependent processes that are hosting activities.
2591            return index;
2592        }
2593
2594        mLruProcesses.remove(lrui);
2595        if (index > 0) {
2596            index--;
2597        }
2598        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2599                + " in LRU list: " + app);
2600        mLruProcesses.add(index, app);
2601        return index;
2602    }
2603
2604    final void removeLruProcessLocked(ProcessRecord app) {
2605        int lrui = mLruProcesses.lastIndexOf(app);
2606        if (lrui >= 0) {
2607            if (lrui <= mLruProcessActivityStart) {
2608                mLruProcessActivityStart--;
2609            }
2610            if (lrui <= mLruProcessServiceStart) {
2611                mLruProcessServiceStart--;
2612            }
2613            mLruProcesses.remove(lrui);
2614        }
2615    }
2616
2617    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2618            ProcessRecord client) {
2619        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2620                || app.treatLikeActivity;
2621        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2622        if (!activityChange && hasActivity) {
2623            // The process has activities, so we are only allowing activity-based adjustments
2624            // to move it.  It should be kept in the front of the list with other
2625            // processes that have activities, and we don't want those to change their
2626            // order except due to activity operations.
2627            return;
2628        }
2629
2630        mLruSeq++;
2631        final long now = SystemClock.uptimeMillis();
2632        app.lastActivityTime = now;
2633
2634        // First a quick reject: if the app is already at the position we will
2635        // put it, then there is nothing to do.
2636        if (hasActivity) {
2637            final int N = mLruProcesses.size();
2638            if (N > 0 && mLruProcesses.get(N-1) == app) {
2639                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2640                return;
2641            }
2642        } else {
2643            if (mLruProcessServiceStart > 0
2644                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2645                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2646                return;
2647            }
2648        }
2649
2650        int lrui = mLruProcesses.lastIndexOf(app);
2651
2652        if (app.persistent && lrui >= 0) {
2653            // We don't care about the position of persistent processes, as long as
2654            // they are in the list.
2655            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2656            return;
2657        }
2658
2659        /* In progress: compute new position first, so we can avoid doing work
2660           if the process is not actually going to move.  Not yet working.
2661        int addIndex;
2662        int nextIndex;
2663        boolean inActivity = false, inService = false;
2664        if (hasActivity) {
2665            // Process has activities, put it at the very tipsy-top.
2666            addIndex = mLruProcesses.size();
2667            nextIndex = mLruProcessServiceStart;
2668            inActivity = true;
2669        } else if (hasService) {
2670            // Process has services, put it at the top of the service list.
2671            addIndex = mLruProcessActivityStart;
2672            nextIndex = mLruProcessServiceStart;
2673            inActivity = true;
2674            inService = true;
2675        } else  {
2676            // Process not otherwise of interest, it goes to the top of the non-service area.
2677            addIndex = mLruProcessServiceStart;
2678            if (client != null) {
2679                int clientIndex = mLruProcesses.lastIndexOf(client);
2680                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2681                        + app);
2682                if (clientIndex >= 0 && addIndex > clientIndex) {
2683                    addIndex = clientIndex;
2684                }
2685            }
2686            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2687        }
2688
2689        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2690                + mLruProcessActivityStart + "): " + app);
2691        */
2692
2693        if (lrui >= 0) {
2694            if (lrui < mLruProcessActivityStart) {
2695                mLruProcessActivityStart--;
2696            }
2697            if (lrui < mLruProcessServiceStart) {
2698                mLruProcessServiceStart--;
2699            }
2700            /*
2701            if (addIndex > lrui) {
2702                addIndex--;
2703            }
2704            if (nextIndex > lrui) {
2705                nextIndex--;
2706            }
2707            */
2708            mLruProcesses.remove(lrui);
2709        }
2710
2711        /*
2712        mLruProcesses.add(addIndex, app);
2713        if (inActivity) {
2714            mLruProcessActivityStart++;
2715        }
2716        if (inService) {
2717            mLruProcessActivityStart++;
2718        }
2719        */
2720
2721        int nextIndex;
2722        if (hasActivity) {
2723            final int N = mLruProcesses.size();
2724            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2725                // Process doesn't have activities, but has clients with
2726                // activities...  move it up, but one below the top (the top
2727                // should always have a real activity).
2728                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2729                mLruProcesses.add(N-1, app);
2730                // To keep it from spamming the LRU list (by making a bunch of clients),
2731                // we will push down any other entries owned by the app.
2732                final int uid = app.info.uid;
2733                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2734                    ProcessRecord subProc = mLruProcesses.get(i);
2735                    if (subProc.info.uid == uid) {
2736                        // We want to push this one down the list.  If the process after
2737                        // it is for the same uid, however, don't do so, because we don't
2738                        // want them internally to be re-ordered.
2739                        if (mLruProcesses.get(i-1).info.uid != uid) {
2740                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2741                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2742                            ProcessRecord tmp = mLruProcesses.get(i);
2743                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2744                            mLruProcesses.set(i-1, tmp);
2745                            i--;
2746                        }
2747                    } else {
2748                        // A gap, we can stop here.
2749                        break;
2750                    }
2751                }
2752            } else {
2753                // Process has activities, put it at the very tipsy-top.
2754                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2755                mLruProcesses.add(app);
2756            }
2757            nextIndex = mLruProcessServiceStart;
2758        } else if (hasService) {
2759            // Process has services, put it at the top of the service list.
2760            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2761            mLruProcesses.add(mLruProcessActivityStart, app);
2762            nextIndex = mLruProcessServiceStart;
2763            mLruProcessActivityStart++;
2764        } else  {
2765            // Process not otherwise of interest, it goes to the top of the non-service area.
2766            int index = mLruProcessServiceStart;
2767            if (client != null) {
2768                // If there is a client, don't allow the process to be moved up higher
2769                // in the list than that client.
2770                int clientIndex = mLruProcesses.lastIndexOf(client);
2771                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2772                        + " when updating " + app);
2773                if (clientIndex <= lrui) {
2774                    // Don't allow the client index restriction to push it down farther in the
2775                    // list than it already is.
2776                    clientIndex = lrui;
2777                }
2778                if (clientIndex >= 0 && index > clientIndex) {
2779                    index = clientIndex;
2780                }
2781            }
2782            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2783            mLruProcesses.add(index, app);
2784            nextIndex = index-1;
2785            mLruProcessActivityStart++;
2786            mLruProcessServiceStart++;
2787        }
2788
2789        // If the app is currently using a content provider or service,
2790        // bump those processes as well.
2791        for (int j=app.connections.size()-1; j>=0; j--) {
2792            ConnectionRecord cr = app.connections.valueAt(j);
2793            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2794                    && cr.binding.service.app != null
2795                    && cr.binding.service.app.lruSeq != mLruSeq
2796                    && !cr.binding.service.app.persistent) {
2797                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2798                        "service connection", cr, app);
2799            }
2800        }
2801        for (int j=app.conProviders.size()-1; j>=0; j--) {
2802            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2803            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2804                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2805                        "provider reference", cpr, app);
2806            }
2807        }
2808    }
2809
2810    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2811        if (uid == Process.SYSTEM_UID) {
2812            // The system gets to run in any process.  If there are multiple
2813            // processes with the same uid, just pick the first (this
2814            // should never happen).
2815            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2816            if (procs == null) return null;
2817            final int N = procs.size();
2818            for (int i = 0; i < N; i++) {
2819                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2820            }
2821        }
2822        ProcessRecord proc = mProcessNames.get(processName, uid);
2823        if (false && proc != null && !keepIfLarge
2824                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2825                && proc.lastCachedPss >= 4000) {
2826            // Turn this condition on to cause killing to happen regularly, for testing.
2827            if (proc.baseProcessTracker != null) {
2828                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2829            }
2830            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2831        } else if (proc != null && !keepIfLarge
2832                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2833                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2834            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2835            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2836                if (proc.baseProcessTracker != null) {
2837                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2838                }
2839                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2840            }
2841        }
2842        return proc;
2843    }
2844
2845    void ensurePackageDexOpt(String packageName) {
2846        IPackageManager pm = AppGlobals.getPackageManager();
2847        try {
2848            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2849                mDidDexOpt = true;
2850            }
2851        } catch (RemoteException e) {
2852        }
2853    }
2854
2855    boolean isNextTransitionForward() {
2856        int transit = mWindowManager.getPendingAppTransition();
2857        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2858                || transit == AppTransition.TRANSIT_TASK_OPEN
2859                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2860    }
2861
2862    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2863            String processName, String abiOverride, int uid, Runnable crashHandler) {
2864        synchronized(this) {
2865            ApplicationInfo info = new ApplicationInfo();
2866            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2867            // For isolated processes, the former contains the parent's uid and the latter the
2868            // actual uid of the isolated process.
2869            // In the special case introduced by this method (which is, starting an isolated
2870            // process directly from the SystemServer without an actual parent app process) the
2871            // closest thing to a parent's uid is SYSTEM_UID.
2872            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2873            // the |isolated| logic in the ProcessRecord constructor.
2874            info.uid = Process.SYSTEM_UID;
2875            info.processName = processName;
2876            info.className = entryPoint;
2877            info.packageName = "android";
2878            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2879                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2880                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2881                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2882                    crashHandler);
2883            return proc != null ? proc.pid : 0;
2884        }
2885    }
2886
2887    final ProcessRecord startProcessLocked(String processName,
2888            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2889            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2890            boolean isolated, boolean keepIfLarge) {
2891        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2892                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2893                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2894                null /* crashHandler */);
2895    }
2896
2897    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2898            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2899            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2900            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2901        long startTime = SystemClock.elapsedRealtime();
2902        ProcessRecord app;
2903        if (!isolated) {
2904            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2905            checkTime(startTime, "startProcess: after getProcessRecord");
2906        } else {
2907            // If this is an isolated process, it can't re-use an existing process.
2908            app = null;
2909        }
2910        // We don't have to do anything more if:
2911        // (1) There is an existing application record; and
2912        // (2) The caller doesn't think it is dead, OR there is no thread
2913        //     object attached to it so we know it couldn't have crashed; and
2914        // (3) There is a pid assigned to it, so it is either starting or
2915        //     already running.
2916        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2917                + " app=" + app + " knownToBeDead=" + knownToBeDead
2918                + " thread=" + (app != null ? app.thread : null)
2919                + " pid=" + (app != null ? app.pid : -1));
2920        if (app != null && app.pid > 0) {
2921            if (!knownToBeDead || app.thread == null) {
2922                // We already have the app running, or are waiting for it to
2923                // come up (we have a pid but not yet its thread), so keep it.
2924                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2925                // If this is a new package in the process, add the package to the list
2926                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2927                checkTime(startTime, "startProcess: done, added package to proc");
2928                return app;
2929            }
2930
2931            // An application record is attached to a previous process,
2932            // clean it up now.
2933            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2934            checkTime(startTime, "startProcess: bad proc running, killing");
2935            Process.killProcessGroup(app.info.uid, app.pid);
2936            handleAppDiedLocked(app, true, true);
2937            checkTime(startTime, "startProcess: done killing old proc");
2938        }
2939
2940        String hostingNameStr = hostingName != null
2941                ? hostingName.flattenToShortString() : null;
2942
2943        if (!isolated) {
2944            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2945                // If we are in the background, then check to see if this process
2946                // is bad.  If so, we will just silently fail.
2947                if (mBadProcesses.get(info.processName, info.uid) != null) {
2948                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2949                            + "/" + info.processName);
2950                    return null;
2951                }
2952            } else {
2953                // When the user is explicitly starting a process, then clear its
2954                // crash count so that we won't make it bad until they see at
2955                // least one crash dialog again, and make the process good again
2956                // if it had been bad.
2957                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2958                        + "/" + info.processName);
2959                mProcessCrashTimes.remove(info.processName, info.uid);
2960                if (mBadProcesses.get(info.processName, info.uid) != null) {
2961                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2962                            UserHandle.getUserId(info.uid), info.uid,
2963                            info.processName);
2964                    mBadProcesses.remove(info.processName, info.uid);
2965                    if (app != null) {
2966                        app.bad = false;
2967                    }
2968                }
2969            }
2970        }
2971
2972        if (app == null) {
2973            checkTime(startTime, "startProcess: creating new process record");
2974            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2975            app.crashHandler = crashHandler;
2976            if (app == null) {
2977                Slog.w(TAG, "Failed making new process record for "
2978                        + processName + "/" + info.uid + " isolated=" + isolated);
2979                return null;
2980            }
2981            mProcessNames.put(processName, app.uid, app);
2982            if (isolated) {
2983                mIsolatedProcesses.put(app.uid, app);
2984            }
2985            checkTime(startTime, "startProcess: done creating new process record");
2986        } else {
2987            // If this is a new package in the process, add the package to the list
2988            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2989            checkTime(startTime, "startProcess: added package to existing proc");
2990        }
2991
2992        // If the system is not ready yet, then hold off on starting this
2993        // process until it is.
2994        if (!mProcessesReady
2995                && !isAllowedWhileBooting(info)
2996                && !allowWhileBooting) {
2997            if (!mProcessesOnHold.contains(app)) {
2998                mProcessesOnHold.add(app);
2999            }
3000            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3001            return app;
3002        }
3003
3004        startProcessLocked(
3005                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3006        checkTime(startTime, "startProcess: done starting proc!");
3007        return (app.pid != 0) ? app : null;
3008    }
3009
3010    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3011        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3012    }
3013
3014    private final void startProcessLocked(ProcessRecord app,
3015            String hostingType, String hostingNameStr) {
3016        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3017                null /* entryPoint */, null /* entryPointArgs */);
3018    }
3019
3020    private final void startProcessLocked(ProcessRecord app, String hostingType,
3021            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3022        long startTime = SystemClock.elapsedRealtime();
3023        if (app.pid > 0 && app.pid != MY_PID) {
3024            checkTime(startTime, "startProcess: removing from pids map");
3025            synchronized (mPidsSelfLocked) {
3026                mPidsSelfLocked.remove(app.pid);
3027                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3028            }
3029            checkTime(startTime, "startProcess: done removing from pids map");
3030            app.setPid(0);
3031        }
3032
3033        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3034                "startProcessLocked removing on hold: " + app);
3035        mProcessesOnHold.remove(app);
3036
3037        checkTime(startTime, "startProcess: starting to update cpu stats");
3038        updateCpuStats();
3039        checkTime(startTime, "startProcess: done updating cpu stats");
3040
3041        try {
3042            int uid = app.uid;
3043
3044            int[] gids = null;
3045            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3046            if (!app.isolated) {
3047                int[] permGids = null;
3048                try {
3049                    checkTime(startTime, "startProcess: getting gids from package manager");
3050                    final PackageManager pm = mContext.getPackageManager();
3051                    permGids = pm.getPackageGids(app.info.packageName);
3052
3053                    if (Environment.isExternalStorageEmulated()) {
3054                        checkTime(startTime, "startProcess: checking external storage perm");
3055                        if (pm.checkPermission(
3056                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3057                                app.info.packageName) == PERMISSION_GRANTED) {
3058                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3059                        } else {
3060                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3061                        }
3062                    }
3063                } catch (PackageManager.NameNotFoundException e) {
3064                    Slog.w(TAG, "Unable to retrieve gids", e);
3065                }
3066
3067                /*
3068                 * Add shared application and profile GIDs so applications can share some
3069                 * resources like shared libraries and access user-wide resources
3070                 */
3071                if (permGids == null) {
3072                    gids = new int[2];
3073                } else {
3074                    gids = new int[permGids.length + 2];
3075                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3076                }
3077                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3078                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3079            }
3080            checkTime(startTime, "startProcess: building args");
3081            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3082                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3083                        && mTopComponent != null
3084                        && app.processName.equals(mTopComponent.getPackageName())) {
3085                    uid = 0;
3086                }
3087                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3088                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3089                    uid = 0;
3090                }
3091            }
3092            int debugFlags = 0;
3093            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3094                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3095                // Also turn on CheckJNI for debuggable apps. It's quite
3096                // awkward to turn on otherwise.
3097                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3098            }
3099            // Run the app in safe mode if its manifest requests so or the
3100            // system is booted in safe mode.
3101            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3102                mSafeMode == true) {
3103                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3104            }
3105            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3106                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3107            }
3108            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3109                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3110            }
3111            if ("1".equals(SystemProperties.get("debug.assert"))) {
3112                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3113            }
3114
3115            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3116            if (requiredAbi == null) {
3117                requiredAbi = Build.SUPPORTED_ABIS[0];
3118            }
3119
3120            // Start the process.  It will either succeed and return a result containing
3121            // the PID of the new process, or else throw a RuntimeException.
3122            boolean isActivityProcess = (entryPoint == null);
3123            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3124            checkTime(startTime, "startProcess: asking zygote to start proc");
3125            Process.ProcessStartResult startResult = Process.start(entryPoint,
3126                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3127                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3128            checkTime(startTime, "startProcess: returned from zygote!");
3129
3130            checkTime(startTime, "startProcess: noting battery stats update");
3131            if (app.isolated) {
3132                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3133            }
3134            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3135            checkTime(startTime, "startProcess: done updating battery stats");
3136
3137            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3138                    UserHandle.getUserId(uid), startResult.pid, uid,
3139                    app.processName, hostingType,
3140                    hostingNameStr != null ? hostingNameStr : "");
3141
3142            if (app.persistent) {
3143                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3144            }
3145
3146            checkTime(startTime, "startProcess: building log message");
3147            StringBuilder buf = mStringBuilder;
3148            buf.setLength(0);
3149            buf.append("Start proc ");
3150            buf.append(app.processName);
3151            if (!isActivityProcess) {
3152                buf.append(" [");
3153                buf.append(entryPoint);
3154                buf.append("]");
3155            }
3156            buf.append(" for ");
3157            buf.append(hostingType);
3158            if (hostingNameStr != null) {
3159                buf.append(" ");
3160                buf.append(hostingNameStr);
3161            }
3162            buf.append(": pid=");
3163            buf.append(startResult.pid);
3164            buf.append(" uid=");
3165            buf.append(uid);
3166            buf.append(" gids={");
3167            if (gids != null) {
3168                for (int gi=0; gi<gids.length; gi++) {
3169                    if (gi != 0) buf.append(", ");
3170                    buf.append(gids[gi]);
3171
3172                }
3173            }
3174            buf.append("}");
3175            if (requiredAbi != null) {
3176                buf.append(" abi=");
3177                buf.append(requiredAbi);
3178            }
3179            Slog.i(TAG, buf.toString());
3180            app.setPid(startResult.pid);
3181            app.usingWrapper = startResult.usingWrapper;
3182            app.removed = false;
3183            app.killedByAm = false;
3184            checkTime(startTime, "startProcess: starting to update pids map");
3185            synchronized (mPidsSelfLocked) {
3186                this.mPidsSelfLocked.put(startResult.pid, app);
3187                if (isActivityProcess) {
3188                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3189                    msg.obj = app;
3190                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3191                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3192                }
3193            }
3194            checkTime(startTime, "startProcess: done updating pids map");
3195        } catch (RuntimeException e) {
3196            // XXX do better error recovery.
3197            app.setPid(0);
3198            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3199            if (app.isolated) {
3200                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3201            }
3202            Slog.e(TAG, "Failure starting process " + app.processName, e);
3203        }
3204    }
3205
3206    void updateUsageStats(ActivityRecord component, boolean resumed) {
3207        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3208        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3209        if (resumed) {
3210            if (mUsageStatsService != null) {
3211                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3212                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3213            }
3214            synchronized (stats) {
3215                stats.noteActivityResumedLocked(component.app.uid);
3216            }
3217        } else {
3218            if (mUsageStatsService != null) {
3219                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3220                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3221            }
3222            synchronized (stats) {
3223                stats.noteActivityPausedLocked(component.app.uid);
3224            }
3225        }
3226    }
3227
3228    Intent getHomeIntent() {
3229        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3230        intent.setComponent(mTopComponent);
3231        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3232            intent.addCategory(Intent.CATEGORY_HOME);
3233        }
3234        return intent;
3235    }
3236
3237    boolean startHomeActivityLocked(int userId) {
3238        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3239                && mTopAction == null) {
3240            // We are running in factory test mode, but unable to find
3241            // the factory test app, so just sit around displaying the
3242            // error message and don't try to start anything.
3243            return false;
3244        }
3245        Intent intent = getHomeIntent();
3246        ActivityInfo aInfo =
3247            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3248        if (aInfo != null) {
3249            intent.setComponent(new ComponentName(
3250                    aInfo.applicationInfo.packageName, aInfo.name));
3251            // Don't do this if the home app is currently being
3252            // instrumented.
3253            aInfo = new ActivityInfo(aInfo);
3254            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3255            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3256                    aInfo.applicationInfo.uid, true);
3257            if (app == null || app.instrumentationClass == null) {
3258                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3259                mStackSupervisor.startHomeActivity(intent, aInfo);
3260            }
3261        }
3262
3263        return true;
3264    }
3265
3266    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3267        ActivityInfo ai = null;
3268        ComponentName comp = intent.getComponent();
3269        try {
3270            if (comp != null) {
3271                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3272            } else {
3273                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3274                        intent,
3275                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3276                            flags, userId);
3277
3278                if (info != null) {
3279                    ai = info.activityInfo;
3280                }
3281            }
3282        } catch (RemoteException e) {
3283            // ignore
3284        }
3285
3286        return ai;
3287    }
3288
3289    /**
3290     * Starts the "new version setup screen" if appropriate.
3291     */
3292    void startSetupActivityLocked() {
3293        // Only do this once per boot.
3294        if (mCheckedForSetup) {
3295            return;
3296        }
3297
3298        // We will show this screen if the current one is a different
3299        // version than the last one shown, and we are not running in
3300        // low-level factory test mode.
3301        final ContentResolver resolver = mContext.getContentResolver();
3302        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3303                Settings.Global.getInt(resolver,
3304                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3305            mCheckedForSetup = true;
3306
3307            // See if we should be showing the platform update setup UI.
3308            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3309            List<ResolveInfo> ris = mContext.getPackageManager()
3310                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3311
3312            // We don't allow third party apps to replace this.
3313            ResolveInfo ri = null;
3314            for (int i=0; ris != null && i<ris.size(); i++) {
3315                if ((ris.get(i).activityInfo.applicationInfo.flags
3316                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3317                    ri = ris.get(i);
3318                    break;
3319                }
3320            }
3321
3322            if (ri != null) {
3323                String vers = ri.activityInfo.metaData != null
3324                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3325                        : null;
3326                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3327                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3328                            Intent.METADATA_SETUP_VERSION);
3329                }
3330                String lastVers = Settings.Secure.getString(
3331                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3332                if (vers != null && !vers.equals(lastVers)) {
3333                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3334                    intent.setComponent(new ComponentName(
3335                            ri.activityInfo.packageName, ri.activityInfo.name));
3336                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3337                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3338                            null);
3339                }
3340            }
3341        }
3342    }
3343
3344    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3345        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3346    }
3347
3348    void enforceNotIsolatedCaller(String caller) {
3349        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3350            throw new SecurityException("Isolated process not allowed to call " + caller);
3351        }
3352    }
3353
3354    @Override
3355    public int getFrontActivityScreenCompatMode() {
3356        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3357        synchronized (this) {
3358            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3359        }
3360    }
3361
3362    @Override
3363    public void setFrontActivityScreenCompatMode(int mode) {
3364        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3365                "setFrontActivityScreenCompatMode");
3366        synchronized (this) {
3367            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3368        }
3369    }
3370
3371    @Override
3372    public int getPackageScreenCompatMode(String packageName) {
3373        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3374        synchronized (this) {
3375            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3376        }
3377    }
3378
3379    @Override
3380    public void setPackageScreenCompatMode(String packageName, int mode) {
3381        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3382                "setPackageScreenCompatMode");
3383        synchronized (this) {
3384            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3385        }
3386    }
3387
3388    @Override
3389    public boolean getPackageAskScreenCompat(String packageName) {
3390        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3391        synchronized (this) {
3392            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3393        }
3394    }
3395
3396    @Override
3397    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3398        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3399                "setPackageAskScreenCompat");
3400        synchronized (this) {
3401            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3402        }
3403    }
3404
3405    private void dispatchProcessesChanged() {
3406        int N;
3407        synchronized (this) {
3408            N = mPendingProcessChanges.size();
3409            if (mActiveProcessChanges.length < N) {
3410                mActiveProcessChanges = new ProcessChangeItem[N];
3411            }
3412            mPendingProcessChanges.toArray(mActiveProcessChanges);
3413            mAvailProcessChanges.addAll(mPendingProcessChanges);
3414            mPendingProcessChanges.clear();
3415            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3416        }
3417
3418        int i = mProcessObservers.beginBroadcast();
3419        while (i > 0) {
3420            i--;
3421            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3422            if (observer != null) {
3423                try {
3424                    for (int j=0; j<N; j++) {
3425                        ProcessChangeItem item = mActiveProcessChanges[j];
3426                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3427                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3428                                    + item.pid + " uid=" + item.uid + ": "
3429                                    + item.foregroundActivities);
3430                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3431                                    item.foregroundActivities);
3432                        }
3433                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3434                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3435                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3436                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3437                        }
3438                    }
3439                } catch (RemoteException e) {
3440                }
3441            }
3442        }
3443        mProcessObservers.finishBroadcast();
3444    }
3445
3446    private void dispatchProcessDied(int pid, int uid) {
3447        int i = mProcessObservers.beginBroadcast();
3448        while (i > 0) {
3449            i--;
3450            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3451            if (observer != null) {
3452                try {
3453                    observer.onProcessDied(pid, uid);
3454                } catch (RemoteException e) {
3455                }
3456            }
3457        }
3458        mProcessObservers.finishBroadcast();
3459    }
3460
3461    @Override
3462    public final int startActivity(IApplicationThread caller, String callingPackage,
3463            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3464            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3465        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3466            resultWho, requestCode, startFlags, profilerInfo, options,
3467            UserHandle.getCallingUserId());
3468    }
3469
3470    @Override
3471    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3472            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3473            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3474        enforceNotIsolatedCaller("startActivity");
3475        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3476                false, ALLOW_FULL_ONLY, "startActivity", null);
3477        // TODO: Switch to user app stacks here.
3478        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3479                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3480                profilerInfo, null, null, options, userId, null, null);
3481    }
3482
3483    @Override
3484    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3485            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3486            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3487
3488        // This is very dangerous -- it allows you to perform a start activity (including
3489        // permission grants) as any app that may launch one of your own activities.  So
3490        // we will only allow this to be done from activities that are part of the core framework,
3491        // and then only when they are running as the system.
3492        final ActivityRecord sourceRecord;
3493        final int targetUid;
3494        final String targetPackage;
3495        synchronized (this) {
3496            if (resultTo == null) {
3497                throw new SecurityException("Must be called from an activity");
3498            }
3499            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3500            if (sourceRecord == null) {
3501                throw new SecurityException("Called with bad activity token: " + resultTo);
3502            }
3503            if (!sourceRecord.info.packageName.equals("android")) {
3504                throw new SecurityException(
3505                        "Must be called from an activity that is declared in the android package");
3506            }
3507            if (sourceRecord.app == null) {
3508                throw new SecurityException("Called without a process attached to activity");
3509            }
3510            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3511                // This is still okay, as long as this activity is running under the
3512                // uid of the original calling activity.
3513                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3514                    throw new SecurityException(
3515                            "Calling activity in uid " + sourceRecord.app.uid
3516                                    + " must be system uid or original calling uid "
3517                                    + sourceRecord.launchedFromUid);
3518                }
3519            }
3520            targetUid = sourceRecord.launchedFromUid;
3521            targetPackage = sourceRecord.launchedFromPackage;
3522        }
3523
3524        // TODO: Switch to user app stacks here.
3525        try {
3526            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3527                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3528                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3529            return ret;
3530        } catch (SecurityException e) {
3531            // XXX need to figure out how to propagate to original app.
3532            // A SecurityException here is generally actually a fault of the original
3533            // calling activity (such as a fairly granting permissions), so propagate it
3534            // back to them.
3535            /*
3536            StringBuilder msg = new StringBuilder();
3537            msg.append("While launching");
3538            msg.append(intent.toString());
3539            msg.append(": ");
3540            msg.append(e.getMessage());
3541            */
3542            throw e;
3543        }
3544    }
3545
3546    @Override
3547    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3548            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3549            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3550        enforceNotIsolatedCaller("startActivityAndWait");
3551        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3552                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3553        WaitResult res = new WaitResult();
3554        // TODO: Switch to user app stacks here.
3555        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3556                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3557                options, userId, null, null);
3558        return res;
3559    }
3560
3561    @Override
3562    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3563            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3564            int startFlags, Configuration config, Bundle options, int userId) {
3565        enforceNotIsolatedCaller("startActivityWithConfig");
3566        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3567                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3568        // TODO: Switch to user app stacks here.
3569        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3570                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3571                null, null, config, options, userId, null, null);
3572        return ret;
3573    }
3574
3575    @Override
3576    public int startActivityIntentSender(IApplicationThread caller,
3577            IntentSender intent, Intent fillInIntent, String resolvedType,
3578            IBinder resultTo, String resultWho, int requestCode,
3579            int flagsMask, int flagsValues, Bundle options) {
3580        enforceNotIsolatedCaller("startActivityIntentSender");
3581        // Refuse possible leaked file descriptors
3582        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3583            throw new IllegalArgumentException("File descriptors passed in Intent");
3584        }
3585
3586        IIntentSender sender = intent.getTarget();
3587        if (!(sender instanceof PendingIntentRecord)) {
3588            throw new IllegalArgumentException("Bad PendingIntent object");
3589        }
3590
3591        PendingIntentRecord pir = (PendingIntentRecord)sender;
3592
3593        synchronized (this) {
3594            // If this is coming from the currently resumed activity, it is
3595            // effectively saying that app switches are allowed at this point.
3596            final ActivityStack stack = getFocusedStack();
3597            if (stack.mResumedActivity != null &&
3598                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3599                mAppSwitchesAllowedTime = 0;
3600            }
3601        }
3602        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3603                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3604        return ret;
3605    }
3606
3607    @Override
3608    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3609            Intent intent, String resolvedType, IVoiceInteractionSession session,
3610            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3611            Bundle options, int userId) {
3612        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3613                != PackageManager.PERMISSION_GRANTED) {
3614            String msg = "Permission Denial: startVoiceActivity() from pid="
3615                    + Binder.getCallingPid()
3616                    + ", uid=" + Binder.getCallingUid()
3617                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3618            Slog.w(TAG, msg);
3619            throw new SecurityException(msg);
3620        }
3621        if (session == null || interactor == null) {
3622            throw new NullPointerException("null session or interactor");
3623        }
3624        userId = handleIncomingUser(callingPid, callingUid, userId,
3625                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3626        // TODO: Switch to user app stacks here.
3627        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3628                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3629                null, options, userId, null, null);
3630    }
3631
3632    @Override
3633    public boolean startNextMatchingActivity(IBinder callingActivity,
3634            Intent intent, Bundle options) {
3635        // Refuse possible leaked file descriptors
3636        if (intent != null && intent.hasFileDescriptors() == true) {
3637            throw new IllegalArgumentException("File descriptors passed in Intent");
3638        }
3639
3640        synchronized (this) {
3641            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3642            if (r == null) {
3643                ActivityOptions.abort(options);
3644                return false;
3645            }
3646            if (r.app == null || r.app.thread == null) {
3647                // The caller is not running...  d'oh!
3648                ActivityOptions.abort(options);
3649                return false;
3650            }
3651            intent = new Intent(intent);
3652            // The caller is not allowed to change the data.
3653            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3654            // And we are resetting to find the next component...
3655            intent.setComponent(null);
3656
3657            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3658
3659            ActivityInfo aInfo = null;
3660            try {
3661                List<ResolveInfo> resolves =
3662                    AppGlobals.getPackageManager().queryIntentActivities(
3663                            intent, r.resolvedType,
3664                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3665                            UserHandle.getCallingUserId());
3666
3667                // Look for the original activity in the list...
3668                final int N = resolves != null ? resolves.size() : 0;
3669                for (int i=0; i<N; i++) {
3670                    ResolveInfo rInfo = resolves.get(i);
3671                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3672                            && rInfo.activityInfo.name.equals(r.info.name)) {
3673                        // We found the current one...  the next matching is
3674                        // after it.
3675                        i++;
3676                        if (i<N) {
3677                            aInfo = resolves.get(i).activityInfo;
3678                        }
3679                        if (debug) {
3680                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3681                                    + "/" + r.info.name);
3682                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3683                                    + "/" + aInfo.name);
3684                        }
3685                        break;
3686                    }
3687                }
3688            } catch (RemoteException e) {
3689            }
3690
3691            if (aInfo == null) {
3692                // Nobody who is next!
3693                ActivityOptions.abort(options);
3694                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3695                return false;
3696            }
3697
3698            intent.setComponent(new ComponentName(
3699                    aInfo.applicationInfo.packageName, aInfo.name));
3700            intent.setFlags(intent.getFlags()&~(
3701                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3702                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3703                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3704                    Intent.FLAG_ACTIVITY_NEW_TASK));
3705
3706            // Okay now we need to start the new activity, replacing the
3707            // currently running activity.  This is a little tricky because
3708            // we want to start the new one as if the current one is finished,
3709            // but not finish the current one first so that there is no flicker.
3710            // And thus...
3711            final boolean wasFinishing = r.finishing;
3712            r.finishing = true;
3713
3714            // Propagate reply information over to the new activity.
3715            final ActivityRecord resultTo = r.resultTo;
3716            final String resultWho = r.resultWho;
3717            final int requestCode = r.requestCode;
3718            r.resultTo = null;
3719            if (resultTo != null) {
3720                resultTo.removeResultsLocked(r, resultWho, requestCode);
3721            }
3722
3723            final long origId = Binder.clearCallingIdentity();
3724            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3725                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3726                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3727                    options, false, null, null, null);
3728            Binder.restoreCallingIdentity(origId);
3729
3730            r.finishing = wasFinishing;
3731            if (res != ActivityManager.START_SUCCESS) {
3732                return false;
3733            }
3734            return true;
3735        }
3736    }
3737
3738    @Override
3739    public final int startActivityFromRecents(int taskId, Bundle options) {
3740        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3741            String msg = "Permission Denial: startActivityFromRecents called without " +
3742                    START_TASKS_FROM_RECENTS;
3743            Slog.w(TAG, msg);
3744            throw new SecurityException(msg);
3745        }
3746        return startActivityFromRecentsInner(taskId, options);
3747    }
3748
3749    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3750        final TaskRecord task;
3751        final int callingUid;
3752        final String callingPackage;
3753        final Intent intent;
3754        final int userId;
3755        synchronized (this) {
3756            task = recentTaskForIdLocked(taskId);
3757            if (task == null) {
3758                throw new IllegalArgumentException("Task " + taskId + " not found.");
3759            }
3760            callingUid = task.mCallingUid;
3761            callingPackage = task.mCallingPackage;
3762            intent = task.intent;
3763            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3764            userId = task.userId;
3765        }
3766        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3767                options, userId, null, task);
3768    }
3769
3770    final int startActivityInPackage(int uid, String callingPackage,
3771            Intent intent, String resolvedType, IBinder resultTo,
3772            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3773            IActivityContainer container, TaskRecord inTask) {
3774
3775        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3776                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3777
3778        // TODO: Switch to user app stacks here.
3779        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3780                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3781                null, null, null, options, userId, container, inTask);
3782        return ret;
3783    }
3784
3785    @Override
3786    public final int startActivities(IApplicationThread caller, String callingPackage,
3787            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3788            int userId) {
3789        enforceNotIsolatedCaller("startActivities");
3790        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3791                false, ALLOW_FULL_ONLY, "startActivity", null);
3792        // TODO: Switch to user app stacks here.
3793        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3794                resolvedTypes, resultTo, options, userId);
3795        return ret;
3796    }
3797
3798    final int startActivitiesInPackage(int uid, String callingPackage,
3799            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3800            Bundle options, int userId) {
3801
3802        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3803                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3804        // TODO: Switch to user app stacks here.
3805        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3806                resultTo, options, userId);
3807        return ret;
3808    }
3809
3810    //explicitly remove thd old information in mRecentTasks when removing existing user.
3811    private void removeRecentTasksForUserLocked(int userId) {
3812        if(userId <= 0) {
3813            Slog.i(TAG, "Can't remove recent task on user " + userId);
3814            return;
3815        }
3816
3817        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3818            TaskRecord tr = mRecentTasks.get(i);
3819            if (tr.userId == userId) {
3820                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3821                        + " when finishing user" + userId);
3822                mRecentTasks.remove(i);
3823                tr.removedFromRecents(mTaskPersister);
3824            }
3825        }
3826
3827        // Remove tasks from persistent storage.
3828        mTaskPersister.wakeup(null, true);
3829    }
3830
3831    /**
3832     * Update the recent tasks lists: make sure tasks should still be here (their
3833     * applications / activities still exist), update their availability, fixup ordering
3834     * of affiliations.
3835     */
3836    void cleanupRecentTasksLocked(int userId) {
3837        if (mRecentTasks == null) {
3838            // Happens when called from the packagemanager broadcast before boot.
3839            return;
3840        }
3841
3842        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3843        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3844        final IPackageManager pm = AppGlobals.getPackageManager();
3845        final ActivityInfo dummyAct = new ActivityInfo();
3846        final ApplicationInfo dummyApp = new ApplicationInfo();
3847
3848        int N = mRecentTasks.size();
3849
3850        int[] users = userId == UserHandle.USER_ALL
3851                ? getUsersLocked() : new int[] { userId };
3852        for (int user : users) {
3853            for (int i = 0; i < N; i++) {
3854                TaskRecord task = mRecentTasks.get(i);
3855                if (task.userId != user) {
3856                    // Only look at tasks for the user ID of interest.
3857                    continue;
3858                }
3859                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3860                    // This situation is broken, and we should just get rid of it now.
3861                    mRecentTasks.remove(i);
3862                    task.removedFromRecents(mTaskPersister);
3863                    i--;
3864                    N--;
3865                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3866                    continue;
3867                }
3868                // Check whether this activity is currently available.
3869                if (task.realActivity != null) {
3870                    ActivityInfo ai = availActCache.get(task.realActivity);
3871                    if (ai == null) {
3872                        try {
3873                            ai = pm.getActivityInfo(task.realActivity,
3874                                    PackageManager.GET_UNINSTALLED_PACKAGES
3875                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3876                        } catch (RemoteException e) {
3877                            // Will never happen.
3878                            continue;
3879                        }
3880                        if (ai == null) {
3881                            ai = dummyAct;
3882                        }
3883                        availActCache.put(task.realActivity, ai);
3884                    }
3885                    if (ai == dummyAct) {
3886                        // This could be either because the activity no longer exists, or the
3887                        // app is temporarily gone.  For the former we want to remove the recents
3888                        // entry; for the latter we want to mark it as unavailable.
3889                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3890                        if (app == null) {
3891                            try {
3892                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3893                                        PackageManager.GET_UNINSTALLED_PACKAGES
3894                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3895                            } catch (RemoteException e) {
3896                                // Will never happen.
3897                                continue;
3898                            }
3899                            if (app == null) {
3900                                app = dummyApp;
3901                            }
3902                            availAppCache.put(task.realActivity.getPackageName(), app);
3903                        }
3904                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3905                            // Doesn't exist any more!  Good-bye.
3906                            mRecentTasks.remove(i);
3907                            task.removedFromRecents(mTaskPersister);
3908                            i--;
3909                            N--;
3910                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3911                            continue;
3912                        } else {
3913                            // Otherwise just not available for now.
3914                            if (task.isAvailable) {
3915                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3916                                        + task);
3917                            }
3918                            task.isAvailable = false;
3919                        }
3920                    } else {
3921                        if (!ai.enabled || !ai.applicationInfo.enabled
3922                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3923                            if (task.isAvailable) {
3924                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3925                                        + task + " (enabled=" + ai.enabled + "/"
3926                                        + ai.applicationInfo.enabled +  " flags="
3927                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3928                            }
3929                            task.isAvailable = false;
3930                        } else {
3931                            if (!task.isAvailable) {
3932                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3933                                        + task);
3934                            }
3935                            task.isAvailable = true;
3936                        }
3937                    }
3938                }
3939            }
3940        }
3941
3942        // Verify the affiliate chain for each task.
3943        for (int i = 0; i < N; ) {
3944            TaskRecord task = mRecentTasks.remove(i);
3945            if (mTmpRecents.contains(task)) {
3946                continue;
3947            }
3948            int affiliatedTaskId = task.mAffiliatedTaskId;
3949            while (true) {
3950                TaskRecord next = task.mNextAffiliate;
3951                if (next == null) {
3952                    break;
3953                }
3954                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3955                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3956                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3957                    task.setNextAffiliate(null);
3958                    if (next.mPrevAffiliate == task) {
3959                        next.setPrevAffiliate(null);
3960                    }
3961                    break;
3962                }
3963                if (next.mPrevAffiliate != task) {
3964                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3965                            next.mPrevAffiliate + " task=" + task);
3966                    next.setPrevAffiliate(null);
3967                    task.setNextAffiliate(null);
3968                    break;
3969                }
3970                if (!mRecentTasks.contains(next)) {
3971                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3972                    task.setNextAffiliate(null);
3973                    // We know that next.mPrevAffiliate is always task, from above, so clear
3974                    // its previous affiliate.
3975                    next.setPrevAffiliate(null);
3976                    break;
3977                }
3978                task = next;
3979            }
3980            // task is now the end of the list
3981            do {
3982                mRecentTasks.remove(task);
3983                mRecentTasks.add(i++, task);
3984                mTmpRecents.add(task);
3985                task.inRecents = true;
3986            } while ((task = task.mPrevAffiliate) != null);
3987        }
3988        mTmpRecents.clear();
3989        // mRecentTasks is now in sorted, affiliated order.
3990    }
3991
3992    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3993        int N = mRecentTasks.size();
3994        TaskRecord top = task;
3995        int topIndex = taskIndex;
3996        while (top.mNextAffiliate != null && topIndex > 0) {
3997            top = top.mNextAffiliate;
3998            topIndex--;
3999        }
4000        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4001                + topIndex + " from intial " + taskIndex);
4002        // Find the end of the chain, doing a sanity check along the way.
4003        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4004        int endIndex = topIndex;
4005        TaskRecord prev = top;
4006        while (endIndex < N) {
4007            TaskRecord cur = mRecentTasks.get(endIndex);
4008            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4009                    + endIndex + " " + cur);
4010            if (cur == top) {
4011                // Verify start of the chain.
4012                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4013                    Slog.wtf(TAG, "Bad chain @" + endIndex
4014                            + ": first task has next affiliate: " + prev);
4015                    sane = false;
4016                    break;
4017                }
4018            } else {
4019                // Verify middle of the chain's next points back to the one before.
4020                if (cur.mNextAffiliate != prev
4021                        || cur.mNextAffiliateTaskId != prev.taskId) {
4022                    Slog.wtf(TAG, "Bad chain @" + endIndex
4023                            + ": middle task " + cur + " @" + endIndex
4024                            + " has bad next affiliate "
4025                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4026                            + ", expected " + prev);
4027                    sane = false;
4028                    break;
4029                }
4030            }
4031            if (cur.mPrevAffiliateTaskId == -1) {
4032                // Chain ends here.
4033                if (cur.mPrevAffiliate != null) {
4034                    Slog.wtf(TAG, "Bad chain @" + endIndex
4035                            + ": last task " + cur + " has previous affiliate "
4036                            + cur.mPrevAffiliate);
4037                    sane = false;
4038                }
4039                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4040                break;
4041            } else {
4042                // Verify middle of the chain's prev points to a valid item.
4043                if (cur.mPrevAffiliate == null) {
4044                    Slog.wtf(TAG, "Bad chain @" + endIndex
4045                            + ": task " + cur + " has previous affiliate "
4046                            + cur.mPrevAffiliate + " but should be id "
4047                            + cur.mPrevAffiliate);
4048                    sane = false;
4049                    break;
4050                }
4051            }
4052            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4053                Slog.wtf(TAG, "Bad chain @" + endIndex
4054                        + ": task " + cur + " has affiliated id "
4055                        + cur.mAffiliatedTaskId + " but should be "
4056                        + task.mAffiliatedTaskId);
4057                sane = false;
4058                break;
4059            }
4060            prev = cur;
4061            endIndex++;
4062            if (endIndex >= N) {
4063                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4064                        + ": last task " + prev);
4065                sane = false;
4066                break;
4067            }
4068        }
4069        if (sane) {
4070            if (endIndex < taskIndex) {
4071                Slog.wtf(TAG, "Bad chain @" + endIndex
4072                        + ": did not extend to task " + task + " @" + taskIndex);
4073                sane = false;
4074            }
4075        }
4076        if (sane) {
4077            // All looks good, we can just move all of the affiliated tasks
4078            // to the top.
4079            for (int i=topIndex; i<=endIndex; i++) {
4080                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4081                        + " from " + i + " to " + (i-topIndex));
4082                TaskRecord cur = mRecentTasks.remove(i);
4083                mRecentTasks.add(i-topIndex, cur);
4084            }
4085            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4086                    + " to " + endIndex);
4087            return true;
4088        }
4089
4090        // Whoops, couldn't do it.
4091        return false;
4092    }
4093
4094    final void addRecentTaskLocked(TaskRecord task) {
4095        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4096                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4097
4098        int N = mRecentTasks.size();
4099        // Quick case: check if the top-most recent task is the same.
4100        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4101            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4102            return;
4103        }
4104        // Another quick case: check if this is part of a set of affiliated
4105        // tasks that are at the top.
4106        if (isAffiliated && N > 0 && task.inRecents
4107                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4108            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4109                    + " at top when adding " + task);
4110            return;
4111        }
4112        // Another quick case: never add voice sessions.
4113        if (task.voiceSession != null) {
4114            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4115            return;
4116        }
4117
4118        boolean needAffiliationFix = false;
4119
4120        // Slightly less quick case: the task is already in recents, so all we need
4121        // to do is move it.
4122        if (task.inRecents) {
4123            int taskIndex = mRecentTasks.indexOf(task);
4124            if (taskIndex >= 0) {
4125                if (!isAffiliated) {
4126                    // Simple case: this is not an affiliated task, so we just move it to the front.
4127                    mRecentTasks.remove(taskIndex);
4128                    mRecentTasks.add(0, task);
4129                    notifyTaskPersisterLocked(task, false);
4130                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4131                            + " from " + taskIndex);
4132                    return;
4133                } else {
4134                    // More complicated: need to keep all affiliated tasks together.
4135                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4136                        // All went well.
4137                        return;
4138                    }
4139
4140                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4141                    // everything and then go through our general path of adding a new task.
4142                    needAffiliationFix = true;
4143                }
4144            } else {
4145                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4146                needAffiliationFix = true;
4147            }
4148        }
4149
4150        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4151        trimRecentsForTask(task, true);
4152
4153        N = mRecentTasks.size();
4154        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4155            final TaskRecord tr = mRecentTasks.remove(N - 1);
4156            tr.removedFromRecents(mTaskPersister);
4157            N--;
4158        }
4159        task.inRecents = true;
4160        if (!isAffiliated || needAffiliationFix) {
4161            // If this is a simple non-affiliated task, or we had some failure trying to
4162            // handle it as part of an affilated task, then just place it at the top.
4163            mRecentTasks.add(0, task);
4164        } else if (isAffiliated) {
4165            // If this is a new affiliated task, then move all of the affiliated tasks
4166            // to the front and insert this new one.
4167            TaskRecord other = task.mNextAffiliate;
4168            if (other == null) {
4169                other = task.mPrevAffiliate;
4170            }
4171            if (other != null) {
4172                int otherIndex = mRecentTasks.indexOf(other);
4173                if (otherIndex >= 0) {
4174                    // Insert new task at appropriate location.
4175                    int taskIndex;
4176                    if (other == task.mNextAffiliate) {
4177                        // We found the index of our next affiliation, which is who is
4178                        // before us in the list, so add after that point.
4179                        taskIndex = otherIndex+1;
4180                    } else {
4181                        // We found the index of our previous affiliation, which is who is
4182                        // after us in the list, so add at their position.
4183                        taskIndex = otherIndex;
4184                    }
4185                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4186                            + taskIndex + ": " + task);
4187                    mRecentTasks.add(taskIndex, task);
4188
4189                    // Now move everything to the front.
4190                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4191                        // All went well.
4192                        return;
4193                    }
4194
4195                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4196                    // everything and then go through our general path of adding a new task.
4197                    needAffiliationFix = true;
4198                } else {
4199                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4200                            + other);
4201                    needAffiliationFix = true;
4202                }
4203            } else {
4204                if (DEBUG_RECENTS) Slog.d(TAG,
4205                        "addRecent: adding affiliated task without next/prev:" + task);
4206                needAffiliationFix = true;
4207            }
4208        }
4209        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4210
4211        if (needAffiliationFix) {
4212            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4213            cleanupRecentTasksLocked(task.userId);
4214        }
4215    }
4216
4217    /**
4218     * If needed, remove oldest existing entries in recents that are for the same kind
4219     * of task as the given one.
4220     */
4221    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4222        int N = mRecentTasks.size();
4223        final Intent intent = task.intent;
4224        final boolean document = intent != null && intent.isDocument();
4225
4226        int maxRecents = task.maxRecents - 1;
4227        for (int i=0; i<N; i++) {
4228            final TaskRecord tr = mRecentTasks.get(i);
4229            if (task != tr) {
4230                if (task.userId != tr.userId) {
4231                    continue;
4232                }
4233                if (i > MAX_RECENT_BITMAPS) {
4234                    tr.freeLastThumbnail();
4235                }
4236                final Intent trIntent = tr.intent;
4237                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4238                    (intent == null || !intent.filterEquals(trIntent))) {
4239                    continue;
4240                }
4241                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4242                if (document && trIsDocument) {
4243                    // These are the same document activity (not necessarily the same doc).
4244                    if (maxRecents > 0) {
4245                        --maxRecents;
4246                        continue;
4247                    }
4248                    // Hit the maximum number of documents for this task. Fall through
4249                    // and remove this document from recents.
4250                } else if (document || trIsDocument) {
4251                    // Only one of these is a document. Not the droid we're looking for.
4252                    continue;
4253                }
4254            }
4255
4256            if (!doTrim) {
4257                // If the caller is not actually asking for a trim, just tell them we reached
4258                // a point where the trim would happen.
4259                return i;
4260            }
4261
4262            // Either task and tr are the same or, their affinities match or their intents match
4263            // and neither of them is a document, or they are documents using the same activity
4264            // and their maxRecents has been reached.
4265            tr.disposeThumbnail();
4266            mRecentTasks.remove(i);
4267            if (task != tr) {
4268                tr.removedFromRecents(mTaskPersister);
4269            }
4270            i--;
4271            N--;
4272            if (task.intent == null) {
4273                // If the new recent task we are adding is not fully
4274                // specified, then replace it with the existing recent task.
4275                task = tr;
4276            }
4277            notifyTaskPersisterLocked(tr, false);
4278        }
4279
4280        return -1;
4281    }
4282
4283    @Override
4284    public void reportActivityFullyDrawn(IBinder token) {
4285        synchronized (this) {
4286            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4287            if (r == null) {
4288                return;
4289            }
4290            r.reportFullyDrawnLocked();
4291        }
4292    }
4293
4294    @Override
4295    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4296        synchronized (this) {
4297            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4298            if (r == null) {
4299                return;
4300            }
4301            final long origId = Binder.clearCallingIdentity();
4302            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4303            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4304                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4305            if (config != null) {
4306                r.frozenBeforeDestroy = true;
4307                if (!updateConfigurationLocked(config, r, false, false)) {
4308                    mStackSupervisor.resumeTopActivitiesLocked();
4309                }
4310            }
4311            Binder.restoreCallingIdentity(origId);
4312        }
4313    }
4314
4315    @Override
4316    public int getRequestedOrientation(IBinder token) {
4317        synchronized (this) {
4318            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4319            if (r == null) {
4320                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4321            }
4322            return mWindowManager.getAppOrientation(r.appToken);
4323        }
4324    }
4325
4326    /**
4327     * This is the internal entry point for handling Activity.finish().
4328     *
4329     * @param token The Binder token referencing the Activity we want to finish.
4330     * @param resultCode Result code, if any, from this Activity.
4331     * @param resultData Result data (Intent), if any, from this Activity.
4332     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4333     *            the root Activity in the task.
4334     *
4335     * @return Returns true if the activity successfully finished, or false if it is still running.
4336     */
4337    @Override
4338    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4339            boolean finishTask) {
4340        // Refuse possible leaked file descriptors
4341        if (resultData != null && resultData.hasFileDescriptors() == true) {
4342            throw new IllegalArgumentException("File descriptors passed in Intent");
4343        }
4344
4345        synchronized(this) {
4346            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4347            if (r == null) {
4348                return true;
4349            }
4350            // Keep track of the root activity of the task before we finish it
4351            TaskRecord tr = r.task;
4352            ActivityRecord rootR = tr.getRootActivity();
4353            // Do not allow task to finish in Lock Task mode.
4354            if (tr == mStackSupervisor.mLockTaskModeTask) {
4355                if (rootR == r) {
4356                    mStackSupervisor.showLockTaskToast();
4357                    return false;
4358                }
4359            }
4360            if (mController != null) {
4361                // Find the first activity that is not finishing.
4362                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4363                if (next != null) {
4364                    // ask watcher if this is allowed
4365                    boolean resumeOK = true;
4366                    try {
4367                        resumeOK = mController.activityResuming(next.packageName);
4368                    } catch (RemoteException e) {
4369                        mController = null;
4370                        Watchdog.getInstance().setActivityController(null);
4371                    }
4372
4373                    if (!resumeOK) {
4374                        return false;
4375                    }
4376                }
4377            }
4378            final long origId = Binder.clearCallingIdentity();
4379            try {
4380                boolean res;
4381                if (finishTask && r == rootR) {
4382                    // If requested, remove the task that is associated to this activity only if it
4383                    // was the root activity in the task.  The result code and data is ignored because
4384                    // we don't support returning them across task boundaries.
4385                    res = removeTaskByIdLocked(tr.taskId, 0);
4386                } else {
4387                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4388                            resultData, "app-request", true);
4389                }
4390                return res;
4391            } finally {
4392                Binder.restoreCallingIdentity(origId);
4393            }
4394        }
4395    }
4396
4397    @Override
4398    public final void finishHeavyWeightApp() {
4399        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4400                != PackageManager.PERMISSION_GRANTED) {
4401            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4402                    + Binder.getCallingPid()
4403                    + ", uid=" + Binder.getCallingUid()
4404                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4405            Slog.w(TAG, msg);
4406            throw new SecurityException(msg);
4407        }
4408
4409        synchronized(this) {
4410            if (mHeavyWeightProcess == null) {
4411                return;
4412            }
4413
4414            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4415                    mHeavyWeightProcess.activities);
4416            for (int i=0; i<activities.size(); i++) {
4417                ActivityRecord r = activities.get(i);
4418                if (!r.finishing) {
4419                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4420                            null, "finish-heavy", true);
4421                }
4422            }
4423
4424            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4425                    mHeavyWeightProcess.userId, 0));
4426            mHeavyWeightProcess = null;
4427        }
4428    }
4429
4430    @Override
4431    public void crashApplication(int uid, int initialPid, String packageName,
4432            String message) {
4433        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4434                != PackageManager.PERMISSION_GRANTED) {
4435            String msg = "Permission Denial: crashApplication() from pid="
4436                    + Binder.getCallingPid()
4437                    + ", uid=" + Binder.getCallingUid()
4438                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4439            Slog.w(TAG, msg);
4440            throw new SecurityException(msg);
4441        }
4442
4443        synchronized(this) {
4444            ProcessRecord proc = null;
4445
4446            // Figure out which process to kill.  We don't trust that initialPid
4447            // still has any relation to current pids, so must scan through the
4448            // list.
4449            synchronized (mPidsSelfLocked) {
4450                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4451                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4452                    if (p.uid != uid) {
4453                        continue;
4454                    }
4455                    if (p.pid == initialPid) {
4456                        proc = p;
4457                        break;
4458                    }
4459                    if (p.pkgList.containsKey(packageName)) {
4460                        proc = p;
4461                    }
4462                }
4463            }
4464
4465            if (proc == null) {
4466                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4467                        + " initialPid=" + initialPid
4468                        + " packageName=" + packageName);
4469                return;
4470            }
4471
4472            if (proc.thread != null) {
4473                if (proc.pid == Process.myPid()) {
4474                    Log.w(TAG, "crashApplication: trying to crash self!");
4475                    return;
4476                }
4477                long ident = Binder.clearCallingIdentity();
4478                try {
4479                    proc.thread.scheduleCrash(message);
4480                } catch (RemoteException e) {
4481                }
4482                Binder.restoreCallingIdentity(ident);
4483            }
4484        }
4485    }
4486
4487    @Override
4488    public final void finishSubActivity(IBinder token, String resultWho,
4489            int requestCode) {
4490        synchronized(this) {
4491            final long origId = Binder.clearCallingIdentity();
4492            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4493            if (r != null) {
4494                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4495            }
4496            Binder.restoreCallingIdentity(origId);
4497        }
4498    }
4499
4500    @Override
4501    public boolean finishActivityAffinity(IBinder token) {
4502        synchronized(this) {
4503            final long origId = Binder.clearCallingIdentity();
4504            try {
4505                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4506
4507                ActivityRecord rootR = r.task.getRootActivity();
4508                // Do not allow task to finish in Lock Task mode.
4509                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4510                    if (rootR == r) {
4511                        mStackSupervisor.showLockTaskToast();
4512                        return false;
4513                    }
4514                }
4515                boolean res = false;
4516                if (r != null) {
4517                    res = r.task.stack.finishActivityAffinityLocked(r);
4518                }
4519                return res;
4520            } finally {
4521                Binder.restoreCallingIdentity(origId);
4522            }
4523        }
4524    }
4525
4526    @Override
4527    public void finishVoiceTask(IVoiceInteractionSession session) {
4528        synchronized(this) {
4529            final long origId = Binder.clearCallingIdentity();
4530            try {
4531                mStackSupervisor.finishVoiceTask(session);
4532            } finally {
4533                Binder.restoreCallingIdentity(origId);
4534            }
4535        }
4536
4537    }
4538
4539    @Override
4540    public boolean releaseActivityInstance(IBinder token) {
4541        synchronized(this) {
4542            final long origId = Binder.clearCallingIdentity();
4543            try {
4544                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4545                if (r.task == null || r.task.stack == null) {
4546                    return false;
4547                }
4548                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4549            } finally {
4550                Binder.restoreCallingIdentity(origId);
4551            }
4552        }
4553    }
4554
4555    @Override
4556    public void releaseSomeActivities(IApplicationThread appInt) {
4557        synchronized(this) {
4558            final long origId = Binder.clearCallingIdentity();
4559            try {
4560                ProcessRecord app = getRecordForAppLocked(appInt);
4561                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4562            } finally {
4563                Binder.restoreCallingIdentity(origId);
4564            }
4565        }
4566    }
4567
4568    @Override
4569    public boolean willActivityBeVisible(IBinder token) {
4570        synchronized(this) {
4571            ActivityStack stack = ActivityRecord.getStackLocked(token);
4572            if (stack != null) {
4573                return stack.willActivityBeVisibleLocked(token);
4574            }
4575            return false;
4576        }
4577    }
4578
4579    @Override
4580    public void overridePendingTransition(IBinder token, String packageName,
4581            int enterAnim, int exitAnim) {
4582        synchronized(this) {
4583            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4584            if (self == null) {
4585                return;
4586            }
4587
4588            final long origId = Binder.clearCallingIdentity();
4589
4590            if (self.state == ActivityState.RESUMED
4591                    || self.state == ActivityState.PAUSING) {
4592                mWindowManager.overridePendingAppTransition(packageName,
4593                        enterAnim, exitAnim, null);
4594            }
4595
4596            Binder.restoreCallingIdentity(origId);
4597        }
4598    }
4599
4600    /**
4601     * Main function for removing an existing process from the activity manager
4602     * as a result of that process going away.  Clears out all connections
4603     * to the process.
4604     */
4605    private final void handleAppDiedLocked(ProcessRecord app,
4606            boolean restarting, boolean allowRestart) {
4607        int pid = app.pid;
4608        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4609        if (!restarting) {
4610            removeLruProcessLocked(app);
4611            if (pid > 0) {
4612                ProcessList.remove(pid);
4613            }
4614        }
4615
4616        if (mProfileProc == app) {
4617            clearProfilerLocked();
4618        }
4619
4620        // Remove this application's activities from active lists.
4621        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4622
4623        app.activities.clear();
4624
4625        if (app.instrumentationClass != null) {
4626            Slog.w(TAG, "Crash of app " + app.processName
4627                  + " running instrumentation " + app.instrumentationClass);
4628            Bundle info = new Bundle();
4629            info.putString("shortMsg", "Process crashed.");
4630            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4631        }
4632
4633        if (!restarting) {
4634            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4635                // If there was nothing to resume, and we are not already
4636                // restarting this process, but there is a visible activity that
4637                // is hosted by the process...  then make sure all visible
4638                // activities are running, taking care of restarting this
4639                // process.
4640                if (hasVisibleActivities) {
4641                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4642                }
4643            }
4644        }
4645    }
4646
4647    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4648        IBinder threadBinder = thread.asBinder();
4649        // Find the application record.
4650        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4651            ProcessRecord rec = mLruProcesses.get(i);
4652            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4653                return i;
4654            }
4655        }
4656        return -1;
4657    }
4658
4659    final ProcessRecord getRecordForAppLocked(
4660            IApplicationThread thread) {
4661        if (thread == null) {
4662            return null;
4663        }
4664
4665        int appIndex = getLRURecordIndexForAppLocked(thread);
4666        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4667    }
4668
4669    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4670        // If there are no longer any background processes running,
4671        // and the app that died was not running instrumentation,
4672        // then tell everyone we are now low on memory.
4673        boolean haveBg = false;
4674        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4675            ProcessRecord rec = mLruProcesses.get(i);
4676            if (rec.thread != null
4677                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4678                haveBg = true;
4679                break;
4680            }
4681        }
4682
4683        if (!haveBg) {
4684            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4685            if (doReport) {
4686                long now = SystemClock.uptimeMillis();
4687                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4688                    doReport = false;
4689                } else {
4690                    mLastMemUsageReportTime = now;
4691                }
4692            }
4693            final ArrayList<ProcessMemInfo> memInfos
4694                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4695            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4696            long now = SystemClock.uptimeMillis();
4697            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4698                ProcessRecord rec = mLruProcesses.get(i);
4699                if (rec == dyingProc || rec.thread == null) {
4700                    continue;
4701                }
4702                if (doReport) {
4703                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4704                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4705                }
4706                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4707                    // The low memory report is overriding any current
4708                    // state for a GC request.  Make sure to do
4709                    // heavy/important/visible/foreground processes first.
4710                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4711                        rec.lastRequestedGc = 0;
4712                    } else {
4713                        rec.lastRequestedGc = rec.lastLowMemory;
4714                    }
4715                    rec.reportLowMemory = true;
4716                    rec.lastLowMemory = now;
4717                    mProcessesToGc.remove(rec);
4718                    addProcessToGcListLocked(rec);
4719                }
4720            }
4721            if (doReport) {
4722                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4723                mHandler.sendMessage(msg);
4724            }
4725            scheduleAppGcsLocked();
4726        }
4727    }
4728
4729    final void appDiedLocked(ProcessRecord app) {
4730       appDiedLocked(app, app.pid, app.thread);
4731    }
4732
4733    final void appDiedLocked(ProcessRecord app, int pid,
4734            IApplicationThread thread) {
4735
4736        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4737        synchronized (stats) {
4738            stats.noteProcessDiedLocked(app.info.uid, pid);
4739        }
4740
4741        Process.killProcessGroup(app.info.uid, pid);
4742
4743        // Clean up already done if the process has been re-started.
4744        if (app.pid == pid && app.thread != null &&
4745                app.thread.asBinder() == thread.asBinder()) {
4746            boolean doLowMem = app.instrumentationClass == null;
4747            boolean doOomAdj = doLowMem;
4748            if (!app.killedByAm) {
4749                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4750                        + ") has died.");
4751                mAllowLowerMemLevel = true;
4752            } else {
4753                // Note that we always want to do oom adj to update our state with the
4754                // new number of procs.
4755                mAllowLowerMemLevel = false;
4756                doLowMem = false;
4757            }
4758            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4759            if (DEBUG_CLEANUP) Slog.v(
4760                TAG, "Dying app: " + app + ", pid: " + pid
4761                + ", thread: " + thread.asBinder());
4762            handleAppDiedLocked(app, false, true);
4763
4764            if (doOomAdj) {
4765                updateOomAdjLocked();
4766            }
4767            if (doLowMem) {
4768                doLowMemReportIfNeededLocked(app);
4769            }
4770        } else if (app.pid != pid) {
4771            // A new process has already been started.
4772            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4773                    + ") has died and restarted (pid " + app.pid + ").");
4774            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4775        } else if (DEBUG_PROCESSES) {
4776            Slog.d(TAG, "Received spurious death notification for thread "
4777                    + thread.asBinder());
4778        }
4779    }
4780
4781    /**
4782     * If a stack trace dump file is configured, dump process stack traces.
4783     * @param clearTraces causes the dump file to be erased prior to the new
4784     *    traces being written, if true; when false, the new traces will be
4785     *    appended to any existing file content.
4786     * @param firstPids of dalvik VM processes to dump stack traces for first
4787     * @param lastPids of dalvik VM processes to dump stack traces for last
4788     * @param nativeProcs optional list of native process names to dump stack crawls
4789     * @return file containing stack traces, or null if no dump file is configured
4790     */
4791    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4792            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4793        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4794        if (tracesPath == null || tracesPath.length() == 0) {
4795            return null;
4796        }
4797
4798        File tracesFile = new File(tracesPath);
4799        try {
4800            File tracesDir = tracesFile.getParentFile();
4801            if (!tracesDir.exists()) {
4802                tracesFile.mkdirs();
4803                if (!SELinux.restorecon(tracesDir)) {
4804                    return null;
4805                }
4806            }
4807            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4808
4809            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4810            tracesFile.createNewFile();
4811            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4812        } catch (IOException e) {
4813            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4814            return null;
4815        }
4816
4817        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4818        return tracesFile;
4819    }
4820
4821    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4822            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4823        // Use a FileObserver to detect when traces finish writing.
4824        // The order of traces is considered important to maintain for legibility.
4825        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4826            @Override
4827            public synchronized void onEvent(int event, String path) { notify(); }
4828        };
4829
4830        try {
4831            observer.startWatching();
4832
4833            // First collect all of the stacks of the most important pids.
4834            if (firstPids != null) {
4835                try {
4836                    int num = firstPids.size();
4837                    for (int i = 0; i < num; i++) {
4838                        synchronized (observer) {
4839                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4840                            observer.wait(200);  // Wait for write-close, give up after 200msec
4841                        }
4842                    }
4843                } catch (InterruptedException e) {
4844                    Log.wtf(TAG, e);
4845                }
4846            }
4847
4848            // Next collect the stacks of the native pids
4849            if (nativeProcs != null) {
4850                int[] pids = Process.getPidsForCommands(nativeProcs);
4851                if (pids != null) {
4852                    for (int pid : pids) {
4853                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4854                    }
4855                }
4856            }
4857
4858            // Lastly, measure CPU usage.
4859            if (processCpuTracker != null) {
4860                processCpuTracker.init();
4861                System.gc();
4862                processCpuTracker.update();
4863                try {
4864                    synchronized (processCpuTracker) {
4865                        processCpuTracker.wait(500); // measure over 1/2 second.
4866                    }
4867                } catch (InterruptedException e) {
4868                }
4869                processCpuTracker.update();
4870
4871                // We'll take the stack crawls of just the top apps using CPU.
4872                final int N = processCpuTracker.countWorkingStats();
4873                int numProcs = 0;
4874                for (int i=0; i<N && numProcs<5; i++) {
4875                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4876                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4877                        numProcs++;
4878                        try {
4879                            synchronized (observer) {
4880                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4881                                observer.wait(200);  // Wait for write-close, give up after 200msec
4882                            }
4883                        } catch (InterruptedException e) {
4884                            Log.wtf(TAG, e);
4885                        }
4886
4887                    }
4888                }
4889            }
4890        } finally {
4891            observer.stopWatching();
4892        }
4893    }
4894
4895    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4896        if (true || IS_USER_BUILD) {
4897            return;
4898        }
4899        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4900        if (tracesPath == null || tracesPath.length() == 0) {
4901            return;
4902        }
4903
4904        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4905        StrictMode.allowThreadDiskWrites();
4906        try {
4907            final File tracesFile = new File(tracesPath);
4908            final File tracesDir = tracesFile.getParentFile();
4909            final File tracesTmp = new File(tracesDir, "__tmp__");
4910            try {
4911                if (!tracesDir.exists()) {
4912                    tracesFile.mkdirs();
4913                    if (!SELinux.restorecon(tracesDir.getPath())) {
4914                        return;
4915                    }
4916                }
4917                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4918
4919                if (tracesFile.exists()) {
4920                    tracesTmp.delete();
4921                    tracesFile.renameTo(tracesTmp);
4922                }
4923                StringBuilder sb = new StringBuilder();
4924                Time tobj = new Time();
4925                tobj.set(System.currentTimeMillis());
4926                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4927                sb.append(": ");
4928                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4929                sb.append(" since ");
4930                sb.append(msg);
4931                FileOutputStream fos = new FileOutputStream(tracesFile);
4932                fos.write(sb.toString().getBytes());
4933                if (app == null) {
4934                    fos.write("\n*** No application process!".getBytes());
4935                }
4936                fos.close();
4937                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4938            } catch (IOException e) {
4939                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4940                return;
4941            }
4942
4943            if (app != null) {
4944                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4945                firstPids.add(app.pid);
4946                dumpStackTraces(tracesPath, firstPids, null, null, null);
4947            }
4948
4949            File lastTracesFile = null;
4950            File curTracesFile = null;
4951            for (int i=9; i>=0; i--) {
4952                String name = String.format(Locale.US, "slow%02d.txt", i);
4953                curTracesFile = new File(tracesDir, name);
4954                if (curTracesFile.exists()) {
4955                    if (lastTracesFile != null) {
4956                        curTracesFile.renameTo(lastTracesFile);
4957                    } else {
4958                        curTracesFile.delete();
4959                    }
4960                }
4961                lastTracesFile = curTracesFile;
4962            }
4963            tracesFile.renameTo(curTracesFile);
4964            if (tracesTmp.exists()) {
4965                tracesTmp.renameTo(tracesFile);
4966            }
4967        } finally {
4968            StrictMode.setThreadPolicy(oldPolicy);
4969        }
4970    }
4971
4972    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4973            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4974        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4975        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4976
4977        if (mController != null) {
4978            try {
4979                // 0 == continue, -1 = kill process immediately
4980                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4981                if (res < 0 && app.pid != MY_PID) {
4982                    app.kill("anr", true);
4983                }
4984            } catch (RemoteException e) {
4985                mController = null;
4986                Watchdog.getInstance().setActivityController(null);
4987            }
4988        }
4989
4990        long anrTime = SystemClock.uptimeMillis();
4991        if (MONITOR_CPU_USAGE) {
4992            updateCpuStatsNow();
4993        }
4994
4995        synchronized (this) {
4996            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4997            if (mShuttingDown) {
4998                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4999                return;
5000            } else if (app.notResponding) {
5001                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5002                return;
5003            } else if (app.crashing) {
5004                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5005                return;
5006            }
5007
5008            // In case we come through here for the same app before completing
5009            // this one, mark as anring now so we will bail out.
5010            app.notResponding = true;
5011
5012            // Log the ANR to the event log.
5013            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5014                    app.processName, app.info.flags, annotation);
5015
5016            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5017            firstPids.add(app.pid);
5018
5019            int parentPid = app.pid;
5020            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5021            if (parentPid != app.pid) firstPids.add(parentPid);
5022
5023            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5024
5025            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5026                ProcessRecord r = mLruProcesses.get(i);
5027                if (r != null && r.thread != null) {
5028                    int pid = r.pid;
5029                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5030                        if (r.persistent) {
5031                            firstPids.add(pid);
5032                        } else {
5033                            lastPids.put(pid, Boolean.TRUE);
5034                        }
5035                    }
5036                }
5037            }
5038        }
5039
5040        // Log the ANR to the main log.
5041        StringBuilder info = new StringBuilder();
5042        info.setLength(0);
5043        info.append("ANR in ").append(app.processName);
5044        if (activity != null && activity.shortComponentName != null) {
5045            info.append(" (").append(activity.shortComponentName).append(")");
5046        }
5047        info.append("\n");
5048        info.append("PID: ").append(app.pid).append("\n");
5049        if (annotation != null) {
5050            info.append("Reason: ").append(annotation).append("\n");
5051        }
5052        if (parent != null && parent != activity) {
5053            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5054        }
5055
5056        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5057
5058        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5059                NATIVE_STACKS_OF_INTEREST);
5060
5061        String cpuInfo = null;
5062        if (MONITOR_CPU_USAGE) {
5063            updateCpuStatsNow();
5064            synchronized (mProcessCpuThread) {
5065                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5066            }
5067            info.append(processCpuTracker.printCurrentLoad());
5068            info.append(cpuInfo);
5069        }
5070
5071        info.append(processCpuTracker.printCurrentState(anrTime));
5072
5073        Slog.e(TAG, info.toString());
5074        if (tracesFile == null) {
5075            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5076            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5077        }
5078
5079        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5080                cpuInfo, tracesFile, null);
5081
5082        if (mController != null) {
5083            try {
5084                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5085                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5086                if (res != 0) {
5087                    if (res < 0 && app.pid != MY_PID) {
5088                        app.kill("anr", true);
5089                    } else {
5090                        synchronized (this) {
5091                            mServices.scheduleServiceTimeoutLocked(app);
5092                        }
5093                    }
5094                    return;
5095                }
5096            } catch (RemoteException e) {
5097                mController = null;
5098                Watchdog.getInstance().setActivityController(null);
5099            }
5100        }
5101
5102        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5103        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5104                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5105
5106        synchronized (this) {
5107            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5108                app.kill("bg anr", true);
5109                return;
5110            }
5111
5112            // Set the app's notResponding state, and look up the errorReportReceiver
5113            makeAppNotRespondingLocked(app,
5114                    activity != null ? activity.shortComponentName : null,
5115                    annotation != null ? "ANR " + annotation : "ANR",
5116                    info.toString());
5117
5118            // Bring up the infamous App Not Responding dialog
5119            Message msg = Message.obtain();
5120            HashMap<String, Object> map = new HashMap<String, Object>();
5121            msg.what = SHOW_NOT_RESPONDING_MSG;
5122            msg.obj = map;
5123            msg.arg1 = aboveSystem ? 1 : 0;
5124            map.put("app", app);
5125            if (activity != null) {
5126                map.put("activity", activity);
5127            }
5128
5129            mHandler.sendMessage(msg);
5130        }
5131    }
5132
5133    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5134        if (!mLaunchWarningShown) {
5135            mLaunchWarningShown = true;
5136            mHandler.post(new Runnable() {
5137                @Override
5138                public void run() {
5139                    synchronized (ActivityManagerService.this) {
5140                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5141                        d.show();
5142                        mHandler.postDelayed(new Runnable() {
5143                            @Override
5144                            public void run() {
5145                                synchronized (ActivityManagerService.this) {
5146                                    d.dismiss();
5147                                    mLaunchWarningShown = false;
5148                                }
5149                            }
5150                        }, 4000);
5151                    }
5152                }
5153            });
5154        }
5155    }
5156
5157    @Override
5158    public boolean clearApplicationUserData(final String packageName,
5159            final IPackageDataObserver observer, int userId) {
5160        enforceNotIsolatedCaller("clearApplicationUserData");
5161        int uid = Binder.getCallingUid();
5162        int pid = Binder.getCallingPid();
5163        userId = handleIncomingUser(pid, uid,
5164                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5165        long callingId = Binder.clearCallingIdentity();
5166        try {
5167            IPackageManager pm = AppGlobals.getPackageManager();
5168            int pkgUid = -1;
5169            synchronized(this) {
5170                try {
5171                    pkgUid = pm.getPackageUid(packageName, userId);
5172                } catch (RemoteException e) {
5173                }
5174                if (pkgUid == -1) {
5175                    Slog.w(TAG, "Invalid packageName: " + packageName);
5176                    if (observer != null) {
5177                        try {
5178                            observer.onRemoveCompleted(packageName, false);
5179                        } catch (RemoteException e) {
5180                            Slog.i(TAG, "Observer no longer exists.");
5181                        }
5182                    }
5183                    return false;
5184                }
5185                if (uid == pkgUid || checkComponentPermission(
5186                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5187                        pid, uid, -1, true)
5188                        == PackageManager.PERMISSION_GRANTED) {
5189                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5190                } else {
5191                    throw new SecurityException("PID " + pid + " does not have permission "
5192                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5193                                    + " of package " + packageName);
5194                }
5195
5196                // Remove all tasks match the cleared application package and user
5197                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5198                    final TaskRecord tr = mRecentTasks.get(i);
5199                    final String taskPackageName =
5200                            tr.getBaseIntent().getComponent().getPackageName();
5201                    if (tr.userId != userId) continue;
5202                    if (!taskPackageName.equals(packageName)) continue;
5203                    removeTaskByIdLocked(tr.taskId, 0);
5204                }
5205            }
5206
5207            try {
5208                // Clear application user data
5209                pm.clearApplicationUserData(packageName, observer, userId);
5210
5211                synchronized(this) {
5212                    // Remove all permissions granted from/to this package
5213                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5214                }
5215
5216                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5217                        Uri.fromParts("package", packageName, null));
5218                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5219                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5220                        null, null, 0, null, null, null, false, false, userId);
5221            } catch (RemoteException e) {
5222            }
5223        } finally {
5224            Binder.restoreCallingIdentity(callingId);
5225        }
5226        return true;
5227    }
5228
5229    @Override
5230    public void killBackgroundProcesses(final String packageName, int userId) {
5231        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5232                != PackageManager.PERMISSION_GRANTED &&
5233                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5234                        != PackageManager.PERMISSION_GRANTED) {
5235            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5236                    + Binder.getCallingPid()
5237                    + ", uid=" + Binder.getCallingUid()
5238                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5239            Slog.w(TAG, msg);
5240            throw new SecurityException(msg);
5241        }
5242
5243        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5244                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5245        long callingId = Binder.clearCallingIdentity();
5246        try {
5247            IPackageManager pm = AppGlobals.getPackageManager();
5248            synchronized(this) {
5249                int appId = -1;
5250                try {
5251                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5252                } catch (RemoteException e) {
5253                }
5254                if (appId == -1) {
5255                    Slog.w(TAG, "Invalid packageName: " + packageName);
5256                    return;
5257                }
5258                killPackageProcessesLocked(packageName, appId, userId,
5259                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5260            }
5261        } finally {
5262            Binder.restoreCallingIdentity(callingId);
5263        }
5264    }
5265
5266    @Override
5267    public void killAllBackgroundProcesses() {
5268        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5269                != PackageManager.PERMISSION_GRANTED) {
5270            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5271                    + Binder.getCallingPid()
5272                    + ", uid=" + Binder.getCallingUid()
5273                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5274            Slog.w(TAG, msg);
5275            throw new SecurityException(msg);
5276        }
5277
5278        long callingId = Binder.clearCallingIdentity();
5279        try {
5280            synchronized(this) {
5281                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5282                final int NP = mProcessNames.getMap().size();
5283                for (int ip=0; ip<NP; ip++) {
5284                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5285                    final int NA = apps.size();
5286                    for (int ia=0; ia<NA; ia++) {
5287                        ProcessRecord app = apps.valueAt(ia);
5288                        if (app.persistent) {
5289                            // we don't kill persistent processes
5290                            continue;
5291                        }
5292                        if (app.removed) {
5293                            procs.add(app);
5294                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5295                            app.removed = true;
5296                            procs.add(app);
5297                        }
5298                    }
5299                }
5300
5301                int N = procs.size();
5302                for (int i=0; i<N; i++) {
5303                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5304                }
5305                mAllowLowerMemLevel = true;
5306                updateOomAdjLocked();
5307                doLowMemReportIfNeededLocked(null);
5308            }
5309        } finally {
5310            Binder.restoreCallingIdentity(callingId);
5311        }
5312    }
5313
5314    @Override
5315    public void forceStopPackage(final String packageName, int userId) {
5316        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5317                != PackageManager.PERMISSION_GRANTED) {
5318            String msg = "Permission Denial: forceStopPackage() from pid="
5319                    + Binder.getCallingPid()
5320                    + ", uid=" + Binder.getCallingUid()
5321                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5322            Slog.w(TAG, msg);
5323            throw new SecurityException(msg);
5324        }
5325        final int callingPid = Binder.getCallingPid();
5326        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5327                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5328        long callingId = Binder.clearCallingIdentity();
5329        try {
5330            IPackageManager pm = AppGlobals.getPackageManager();
5331            synchronized(this) {
5332                int[] users = userId == UserHandle.USER_ALL
5333                        ? getUsersLocked() : new int[] { userId };
5334                for (int user : users) {
5335                    int pkgUid = -1;
5336                    try {
5337                        pkgUid = pm.getPackageUid(packageName, user);
5338                    } catch (RemoteException e) {
5339                    }
5340                    if (pkgUid == -1) {
5341                        Slog.w(TAG, "Invalid packageName: " + packageName);
5342                        continue;
5343                    }
5344                    try {
5345                        pm.setPackageStoppedState(packageName, true, user);
5346                    } catch (RemoteException e) {
5347                    } catch (IllegalArgumentException e) {
5348                        Slog.w(TAG, "Failed trying to unstop package "
5349                                + packageName + ": " + e);
5350                    }
5351                    if (isUserRunningLocked(user, false)) {
5352                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5353                    }
5354                }
5355            }
5356        } finally {
5357            Binder.restoreCallingIdentity(callingId);
5358        }
5359    }
5360
5361    @Override
5362    public void addPackageDependency(String packageName) {
5363        synchronized (this) {
5364            int callingPid = Binder.getCallingPid();
5365            if (callingPid == Process.myPid()) {
5366                //  Yeah, um, no.
5367                Slog.w(TAG, "Can't addPackageDependency on system process");
5368                return;
5369            }
5370            ProcessRecord proc;
5371            synchronized (mPidsSelfLocked) {
5372                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5373            }
5374            if (proc != null) {
5375                if (proc.pkgDeps == null) {
5376                    proc.pkgDeps = new ArraySet<String>(1);
5377                }
5378                proc.pkgDeps.add(packageName);
5379            }
5380        }
5381    }
5382
5383    /*
5384     * The pkg name and app id have to be specified.
5385     */
5386    @Override
5387    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5388        if (pkg == null) {
5389            return;
5390        }
5391        // Make sure the uid is valid.
5392        if (appid < 0) {
5393            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5394            return;
5395        }
5396        int callerUid = Binder.getCallingUid();
5397        // Only the system server can kill an application
5398        if (callerUid == Process.SYSTEM_UID) {
5399            // Post an aysnc message to kill the application
5400            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5401            msg.arg1 = appid;
5402            msg.arg2 = 0;
5403            Bundle bundle = new Bundle();
5404            bundle.putString("pkg", pkg);
5405            bundle.putString("reason", reason);
5406            msg.obj = bundle;
5407            mHandler.sendMessage(msg);
5408        } else {
5409            throw new SecurityException(callerUid + " cannot kill pkg: " +
5410                    pkg);
5411        }
5412    }
5413
5414    @Override
5415    public void closeSystemDialogs(String reason) {
5416        enforceNotIsolatedCaller("closeSystemDialogs");
5417
5418        final int pid = Binder.getCallingPid();
5419        final int uid = Binder.getCallingUid();
5420        final long origId = Binder.clearCallingIdentity();
5421        try {
5422            synchronized (this) {
5423                // Only allow this from foreground processes, so that background
5424                // applications can't abuse it to prevent system UI from being shown.
5425                if (uid >= Process.FIRST_APPLICATION_UID) {
5426                    ProcessRecord proc;
5427                    synchronized (mPidsSelfLocked) {
5428                        proc = mPidsSelfLocked.get(pid);
5429                    }
5430                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5431                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5432                                + " from background process " + proc);
5433                        return;
5434                    }
5435                }
5436                closeSystemDialogsLocked(reason);
5437            }
5438        } finally {
5439            Binder.restoreCallingIdentity(origId);
5440        }
5441    }
5442
5443    void closeSystemDialogsLocked(String reason) {
5444        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5445        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5446                | Intent.FLAG_RECEIVER_FOREGROUND);
5447        if (reason != null) {
5448            intent.putExtra("reason", reason);
5449        }
5450        mWindowManager.closeSystemDialogs(reason);
5451
5452        mStackSupervisor.closeSystemDialogsLocked();
5453
5454        broadcastIntentLocked(null, null, intent, null,
5455                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5456                Process.SYSTEM_UID, UserHandle.USER_ALL);
5457    }
5458
5459    @Override
5460    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5461        enforceNotIsolatedCaller("getProcessMemoryInfo");
5462        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5463        for (int i=pids.length-1; i>=0; i--) {
5464            ProcessRecord proc;
5465            int oomAdj;
5466            synchronized (this) {
5467                synchronized (mPidsSelfLocked) {
5468                    proc = mPidsSelfLocked.get(pids[i]);
5469                    oomAdj = proc != null ? proc.setAdj : 0;
5470                }
5471            }
5472            infos[i] = new Debug.MemoryInfo();
5473            Debug.getMemoryInfo(pids[i], infos[i]);
5474            if (proc != null) {
5475                synchronized (this) {
5476                    if (proc.thread != null && proc.setAdj == oomAdj) {
5477                        // Record this for posterity if the process has been stable.
5478                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5479                                infos[i].getTotalUss(), false, proc.pkgList);
5480                    }
5481                }
5482            }
5483        }
5484        return infos;
5485    }
5486
5487    @Override
5488    public long[] getProcessPss(int[] pids) {
5489        enforceNotIsolatedCaller("getProcessPss");
5490        long[] pss = new long[pids.length];
5491        for (int i=pids.length-1; i>=0; i--) {
5492            ProcessRecord proc;
5493            int oomAdj;
5494            synchronized (this) {
5495                synchronized (mPidsSelfLocked) {
5496                    proc = mPidsSelfLocked.get(pids[i]);
5497                    oomAdj = proc != null ? proc.setAdj : 0;
5498                }
5499            }
5500            long[] tmpUss = new long[1];
5501            pss[i] = Debug.getPss(pids[i], tmpUss);
5502            if (proc != null) {
5503                synchronized (this) {
5504                    if (proc.thread != null && proc.setAdj == oomAdj) {
5505                        // Record this for posterity if the process has been stable.
5506                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5507                    }
5508                }
5509            }
5510        }
5511        return pss;
5512    }
5513
5514    @Override
5515    public void killApplicationProcess(String processName, int uid) {
5516        if (processName == null) {
5517            return;
5518        }
5519
5520        int callerUid = Binder.getCallingUid();
5521        // Only the system server can kill an application
5522        if (callerUid == Process.SYSTEM_UID) {
5523            synchronized (this) {
5524                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5525                if (app != null && app.thread != null) {
5526                    try {
5527                        app.thread.scheduleSuicide();
5528                    } catch (RemoteException e) {
5529                        // If the other end already died, then our work here is done.
5530                    }
5531                } else {
5532                    Slog.w(TAG, "Process/uid not found attempting kill of "
5533                            + processName + " / " + uid);
5534                }
5535            }
5536        } else {
5537            throw new SecurityException(callerUid + " cannot kill app process: " +
5538                    processName);
5539        }
5540    }
5541
5542    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5543        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5544                false, true, false, false, UserHandle.getUserId(uid), reason);
5545        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5546                Uri.fromParts("package", packageName, null));
5547        if (!mProcessesReady) {
5548            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5549                    | Intent.FLAG_RECEIVER_FOREGROUND);
5550        }
5551        intent.putExtra(Intent.EXTRA_UID, uid);
5552        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5553        broadcastIntentLocked(null, null, intent,
5554                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5555                false, false,
5556                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5557    }
5558
5559    private void forceStopUserLocked(int userId, String reason) {
5560        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5561        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5562        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5563                | Intent.FLAG_RECEIVER_FOREGROUND);
5564        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5565        broadcastIntentLocked(null, null, intent,
5566                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5567                false, false,
5568                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5569    }
5570
5571    private final boolean killPackageProcessesLocked(String packageName, int appId,
5572            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5573            boolean doit, boolean evenPersistent, String reason) {
5574        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5575
5576        // Remove all processes this package may have touched: all with the
5577        // same UID (except for the system or root user), and all whose name
5578        // matches the package name.
5579        final int NP = mProcessNames.getMap().size();
5580        for (int ip=0; ip<NP; ip++) {
5581            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5582            final int NA = apps.size();
5583            for (int ia=0; ia<NA; ia++) {
5584                ProcessRecord app = apps.valueAt(ia);
5585                if (app.persistent && !evenPersistent) {
5586                    // we don't kill persistent processes
5587                    continue;
5588                }
5589                if (app.removed) {
5590                    if (doit) {
5591                        procs.add(app);
5592                    }
5593                    continue;
5594                }
5595
5596                // Skip process if it doesn't meet our oom adj requirement.
5597                if (app.setAdj < minOomAdj) {
5598                    continue;
5599                }
5600
5601                // If no package is specified, we call all processes under the
5602                // give user id.
5603                if (packageName == null) {
5604                    if (app.userId != userId) {
5605                        continue;
5606                    }
5607                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5608                        continue;
5609                    }
5610                // Package has been specified, we want to hit all processes
5611                // that match it.  We need to qualify this by the processes
5612                // that are running under the specified app and user ID.
5613                } else {
5614                    final boolean isDep = app.pkgDeps != null
5615                            && app.pkgDeps.contains(packageName);
5616                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5617                        continue;
5618                    }
5619                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5620                        continue;
5621                    }
5622                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5623                        continue;
5624                    }
5625                }
5626
5627                // Process has passed all conditions, kill it!
5628                if (!doit) {
5629                    return true;
5630                }
5631                app.removed = true;
5632                procs.add(app);
5633            }
5634        }
5635
5636        int N = procs.size();
5637        for (int i=0; i<N; i++) {
5638            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5639        }
5640        updateOomAdjLocked();
5641        return N > 0;
5642    }
5643
5644    private final boolean forceStopPackageLocked(String name, int appId,
5645            boolean callerWillRestart, boolean purgeCache, boolean doit,
5646            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5647        int i;
5648        int N;
5649
5650        if (userId == UserHandle.USER_ALL && name == null) {
5651            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5652        }
5653
5654        if (appId < 0 && name != null) {
5655            try {
5656                appId = UserHandle.getAppId(
5657                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5658            } catch (RemoteException e) {
5659            }
5660        }
5661
5662        if (doit) {
5663            if (name != null) {
5664                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5665                        + " user=" + userId + ": " + reason);
5666            } else {
5667                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5668            }
5669
5670            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5671            for (int ip=pmap.size()-1; ip>=0; ip--) {
5672                SparseArray<Long> ba = pmap.valueAt(ip);
5673                for (i=ba.size()-1; i>=0; i--) {
5674                    boolean remove = false;
5675                    final int entUid = ba.keyAt(i);
5676                    if (name != null) {
5677                        if (userId == UserHandle.USER_ALL) {
5678                            if (UserHandle.getAppId(entUid) == appId) {
5679                                remove = true;
5680                            }
5681                        } else {
5682                            if (entUid == UserHandle.getUid(userId, appId)) {
5683                                remove = true;
5684                            }
5685                        }
5686                    } else if (UserHandle.getUserId(entUid) == userId) {
5687                        remove = true;
5688                    }
5689                    if (remove) {
5690                        ba.removeAt(i);
5691                    }
5692                }
5693                if (ba.size() == 0) {
5694                    pmap.removeAt(ip);
5695                }
5696            }
5697        }
5698
5699        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5700                -100, callerWillRestart, true, doit, evenPersistent,
5701                name == null ? ("stop user " + userId) : ("stop " + name));
5702
5703        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5704            if (!doit) {
5705                return true;
5706            }
5707            didSomething = true;
5708        }
5709
5710        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5711            if (!doit) {
5712                return true;
5713            }
5714            didSomething = true;
5715        }
5716
5717        if (name == null) {
5718            // Remove all sticky broadcasts from this user.
5719            mStickyBroadcasts.remove(userId);
5720        }
5721
5722        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5723        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5724                userId, providers)) {
5725            if (!doit) {
5726                return true;
5727            }
5728            didSomething = true;
5729        }
5730        N = providers.size();
5731        for (i=0; i<N; i++) {
5732            removeDyingProviderLocked(null, providers.get(i), true);
5733        }
5734
5735        // Remove transient permissions granted from/to this package/user
5736        removeUriPermissionsForPackageLocked(name, userId, false);
5737
5738        if (name == null || uninstalling) {
5739            // Remove pending intents.  For now we only do this when force
5740            // stopping users, because we have some problems when doing this
5741            // for packages -- app widgets are not currently cleaned up for
5742            // such packages, so they can be left with bad pending intents.
5743            if (mIntentSenderRecords.size() > 0) {
5744                Iterator<WeakReference<PendingIntentRecord>> it
5745                        = mIntentSenderRecords.values().iterator();
5746                while (it.hasNext()) {
5747                    WeakReference<PendingIntentRecord> wpir = it.next();
5748                    if (wpir == null) {
5749                        it.remove();
5750                        continue;
5751                    }
5752                    PendingIntentRecord pir = wpir.get();
5753                    if (pir == null) {
5754                        it.remove();
5755                        continue;
5756                    }
5757                    if (name == null) {
5758                        // Stopping user, remove all objects for the user.
5759                        if (pir.key.userId != userId) {
5760                            // Not the same user, skip it.
5761                            continue;
5762                        }
5763                    } else {
5764                        if (UserHandle.getAppId(pir.uid) != appId) {
5765                            // Different app id, skip it.
5766                            continue;
5767                        }
5768                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5769                            // Different user, skip it.
5770                            continue;
5771                        }
5772                        if (!pir.key.packageName.equals(name)) {
5773                            // Different package, skip it.
5774                            continue;
5775                        }
5776                    }
5777                    if (!doit) {
5778                        return true;
5779                    }
5780                    didSomething = true;
5781                    it.remove();
5782                    pir.canceled = true;
5783                    if (pir.key.activity != null) {
5784                        pir.key.activity.pendingResults.remove(pir.ref);
5785                    }
5786                }
5787            }
5788        }
5789
5790        if (doit) {
5791            if (purgeCache && name != null) {
5792                AttributeCache ac = AttributeCache.instance();
5793                if (ac != null) {
5794                    ac.removePackage(name);
5795                }
5796            }
5797            if (mBooted) {
5798                mStackSupervisor.resumeTopActivitiesLocked();
5799                mStackSupervisor.scheduleIdleLocked();
5800            }
5801        }
5802
5803        return didSomething;
5804    }
5805
5806    private final boolean removeProcessLocked(ProcessRecord app,
5807            boolean callerWillRestart, boolean allowRestart, String reason) {
5808        final String name = app.processName;
5809        final int uid = app.uid;
5810        if (DEBUG_PROCESSES) Slog.d(
5811            TAG, "Force removing proc " + app.toShortString() + " (" + name
5812            + "/" + uid + ")");
5813
5814        mProcessNames.remove(name, uid);
5815        mIsolatedProcesses.remove(app.uid);
5816        if (mHeavyWeightProcess == app) {
5817            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5818                    mHeavyWeightProcess.userId, 0));
5819            mHeavyWeightProcess = null;
5820        }
5821        boolean needRestart = false;
5822        if (app.pid > 0 && app.pid != MY_PID) {
5823            int pid = app.pid;
5824            synchronized (mPidsSelfLocked) {
5825                mPidsSelfLocked.remove(pid);
5826                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5827            }
5828            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5829            if (app.isolated) {
5830                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5831            }
5832            app.kill(reason, true);
5833            handleAppDiedLocked(app, true, allowRestart);
5834            removeLruProcessLocked(app);
5835
5836            if (app.persistent && !app.isolated) {
5837                if (!callerWillRestart) {
5838                    addAppLocked(app.info, false, null /* ABI override */);
5839                } else {
5840                    needRestart = true;
5841                }
5842            }
5843        } else {
5844            mRemovedProcesses.add(app);
5845        }
5846
5847        return needRestart;
5848    }
5849
5850    private final void processStartTimedOutLocked(ProcessRecord app) {
5851        final int pid = app.pid;
5852        boolean gone = false;
5853        synchronized (mPidsSelfLocked) {
5854            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5855            if (knownApp != null && knownApp.thread == null) {
5856                mPidsSelfLocked.remove(pid);
5857                gone = true;
5858            }
5859        }
5860
5861        if (gone) {
5862            Slog.w(TAG, "Process " + app + " failed to attach");
5863            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5864                    pid, app.uid, app.processName);
5865            mProcessNames.remove(app.processName, app.uid);
5866            mIsolatedProcesses.remove(app.uid);
5867            if (mHeavyWeightProcess == app) {
5868                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5869                        mHeavyWeightProcess.userId, 0));
5870                mHeavyWeightProcess = null;
5871            }
5872            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5873            if (app.isolated) {
5874                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5875            }
5876            // Take care of any launching providers waiting for this process.
5877            checkAppInLaunchingProvidersLocked(app, true);
5878            // Take care of any services that are waiting for the process.
5879            mServices.processStartTimedOutLocked(app);
5880            app.kill("start timeout", true);
5881            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5882                Slog.w(TAG, "Unattached app died before backup, skipping");
5883                try {
5884                    IBackupManager bm = IBackupManager.Stub.asInterface(
5885                            ServiceManager.getService(Context.BACKUP_SERVICE));
5886                    bm.agentDisconnected(app.info.packageName);
5887                } catch (RemoteException e) {
5888                    // Can't happen; the backup manager is local
5889                }
5890            }
5891            if (isPendingBroadcastProcessLocked(pid)) {
5892                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5893                skipPendingBroadcastLocked(pid);
5894            }
5895        } else {
5896            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5897        }
5898    }
5899
5900    private final boolean attachApplicationLocked(IApplicationThread thread,
5901            int pid) {
5902
5903        // Find the application record that is being attached...  either via
5904        // the pid if we are running in multiple processes, or just pull the
5905        // next app record if we are emulating process with anonymous threads.
5906        ProcessRecord app;
5907        if (pid != MY_PID && pid >= 0) {
5908            synchronized (mPidsSelfLocked) {
5909                app = mPidsSelfLocked.get(pid);
5910            }
5911        } else {
5912            app = null;
5913        }
5914
5915        if (app == null) {
5916            Slog.w(TAG, "No pending application record for pid " + pid
5917                    + " (IApplicationThread " + thread + "); dropping process");
5918            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5919            if (pid > 0 && pid != MY_PID) {
5920                Process.killProcessQuiet(pid);
5921                //TODO: Process.killProcessGroup(app.info.uid, pid);
5922            } else {
5923                try {
5924                    thread.scheduleExit();
5925                } catch (Exception e) {
5926                    // Ignore exceptions.
5927                }
5928            }
5929            return false;
5930        }
5931
5932        // If this application record is still attached to a previous
5933        // process, clean it up now.
5934        if (app.thread != null) {
5935            handleAppDiedLocked(app, true, true);
5936        }
5937
5938        // Tell the process all about itself.
5939
5940        if (localLOGV) Slog.v(
5941                TAG, "Binding process pid " + pid + " to record " + app);
5942
5943        final String processName = app.processName;
5944        try {
5945            AppDeathRecipient adr = new AppDeathRecipient(
5946                    app, pid, thread);
5947            thread.asBinder().linkToDeath(adr, 0);
5948            app.deathRecipient = adr;
5949        } catch (RemoteException e) {
5950            app.resetPackageList(mProcessStats);
5951            startProcessLocked(app, "link fail", processName);
5952            return false;
5953        }
5954
5955        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5956
5957        app.makeActive(thread, mProcessStats);
5958        app.curAdj = app.setAdj = -100;
5959        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5960        app.forcingToForeground = null;
5961        updateProcessForegroundLocked(app, false, false);
5962        app.hasShownUi = false;
5963        app.debugging = false;
5964        app.cached = false;
5965
5966        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5967
5968        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5969        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5970
5971        if (!normalMode) {
5972            Slog.i(TAG, "Launching preboot mode app: " + app);
5973        }
5974
5975        if (localLOGV) Slog.v(
5976            TAG, "New app record " + app
5977            + " thread=" + thread.asBinder() + " pid=" + pid);
5978        try {
5979            int testMode = IApplicationThread.DEBUG_OFF;
5980            if (mDebugApp != null && mDebugApp.equals(processName)) {
5981                testMode = mWaitForDebugger
5982                    ? IApplicationThread.DEBUG_WAIT
5983                    : IApplicationThread.DEBUG_ON;
5984                app.debugging = true;
5985                if (mDebugTransient) {
5986                    mDebugApp = mOrigDebugApp;
5987                    mWaitForDebugger = mOrigWaitForDebugger;
5988                }
5989            }
5990            String profileFile = app.instrumentationProfileFile;
5991            ParcelFileDescriptor profileFd = null;
5992            int samplingInterval = 0;
5993            boolean profileAutoStop = false;
5994            if (mProfileApp != null && mProfileApp.equals(processName)) {
5995                mProfileProc = app;
5996                profileFile = mProfileFile;
5997                profileFd = mProfileFd;
5998                samplingInterval = mSamplingInterval;
5999                profileAutoStop = mAutoStopProfiler;
6000            }
6001            boolean enableOpenGlTrace = false;
6002            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6003                enableOpenGlTrace = true;
6004                mOpenGlTraceApp = null;
6005            }
6006
6007            // If the app is being launched for restore or full backup, set it up specially
6008            boolean isRestrictedBackupMode = false;
6009            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6010                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6011                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6012                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6013            }
6014
6015            ensurePackageDexOpt(app.instrumentationInfo != null
6016                    ? app.instrumentationInfo.packageName
6017                    : app.info.packageName);
6018            if (app.instrumentationClass != null) {
6019                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6020            }
6021            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6022                    + processName + " with config " + mConfiguration);
6023            ApplicationInfo appInfo = app.instrumentationInfo != null
6024                    ? app.instrumentationInfo : app.info;
6025            app.compat = compatibilityInfoForPackageLocked(appInfo);
6026            if (profileFd != null) {
6027                profileFd = profileFd.dup();
6028            }
6029            ProfilerInfo profilerInfo = profileFile == null ? null
6030                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6031            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6032                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6033                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6034                    isRestrictedBackupMode || !normalMode, app.persistent,
6035                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6036                    mCoreSettingsObserver.getCoreSettingsLocked());
6037            updateLruProcessLocked(app, false, null);
6038            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6039        } catch (Exception e) {
6040            // todo: Yikes!  What should we do?  For now we will try to
6041            // start another process, but that could easily get us in
6042            // an infinite loop of restarting processes...
6043            Slog.w(TAG, "Exception thrown during bind!", e);
6044
6045            app.resetPackageList(mProcessStats);
6046            app.unlinkDeathRecipient();
6047            startProcessLocked(app, "bind fail", processName);
6048            return false;
6049        }
6050
6051        // Remove this record from the list of starting applications.
6052        mPersistentStartingProcesses.remove(app);
6053        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6054                "Attach application locked removing on hold: " + app);
6055        mProcessesOnHold.remove(app);
6056
6057        boolean badApp = false;
6058        boolean didSomething = false;
6059
6060        // See if the top visible activity is waiting to run in this process...
6061        if (normalMode) {
6062            try {
6063                if (mStackSupervisor.attachApplicationLocked(app)) {
6064                    didSomething = true;
6065                }
6066            } catch (Exception e) {
6067                badApp = true;
6068            }
6069        }
6070
6071        // Find any services that should be running in this process...
6072        if (!badApp) {
6073            try {
6074                didSomething |= mServices.attachApplicationLocked(app, processName);
6075            } catch (Exception e) {
6076                badApp = true;
6077            }
6078        }
6079
6080        // Check if a next-broadcast receiver is in this process...
6081        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6082            try {
6083                didSomething |= sendPendingBroadcastsLocked(app);
6084            } catch (Exception e) {
6085                // If the app died trying to launch the receiver we declare it 'bad'
6086                badApp = true;
6087            }
6088        }
6089
6090        // Check whether the next backup agent is in this process...
6091        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6092            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6093            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6094            try {
6095                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6096                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6097                        mBackupTarget.backupMode);
6098            } catch (Exception e) {
6099                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6100                e.printStackTrace();
6101            }
6102        }
6103
6104        if (badApp) {
6105            // todo: Also need to kill application to deal with all
6106            // kinds of exceptions.
6107            handleAppDiedLocked(app, false, true);
6108            return false;
6109        }
6110
6111        if (!didSomething) {
6112            updateOomAdjLocked();
6113        }
6114
6115        return true;
6116    }
6117
6118    @Override
6119    public final void attachApplication(IApplicationThread thread) {
6120        synchronized (this) {
6121            int callingPid = Binder.getCallingPid();
6122            final long origId = Binder.clearCallingIdentity();
6123            attachApplicationLocked(thread, callingPid);
6124            Binder.restoreCallingIdentity(origId);
6125        }
6126    }
6127
6128    @Override
6129    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6130        final long origId = Binder.clearCallingIdentity();
6131        synchronized (this) {
6132            ActivityStack stack = ActivityRecord.getStackLocked(token);
6133            if (stack != null) {
6134                ActivityRecord r =
6135                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6136                if (stopProfiling) {
6137                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6138                        try {
6139                            mProfileFd.close();
6140                        } catch (IOException e) {
6141                        }
6142                        clearProfilerLocked();
6143                    }
6144                }
6145            }
6146        }
6147        Binder.restoreCallingIdentity(origId);
6148    }
6149
6150    void postEnableScreenAfterBootLocked() {
6151        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6152    }
6153
6154    void enableScreenAfterBoot() {
6155        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6156                SystemClock.uptimeMillis());
6157        mWindowManager.enableScreenAfterBoot();
6158
6159        synchronized (this) {
6160            updateEventDispatchingLocked();
6161        }
6162    }
6163
6164    @Override
6165    public void showBootMessage(final CharSequence msg, final boolean always) {
6166        enforceNotIsolatedCaller("showBootMessage");
6167        mWindowManager.showBootMessage(msg, always);
6168    }
6169
6170    @Override
6171    public void keyguardWaitingForActivityDrawn() {
6172        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6173        final long token = Binder.clearCallingIdentity();
6174        try {
6175            synchronized (this) {
6176                if (DEBUG_LOCKSCREEN) logLockScreen("");
6177                mWindowManager.keyguardWaitingForActivityDrawn();
6178            }
6179        } finally {
6180            Binder.restoreCallingIdentity(token);
6181        }
6182    }
6183
6184    final void finishBooting() {
6185        // Register receivers to handle package update events
6186        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6187
6188        // Let system services know.
6189        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6190
6191        synchronized (this) {
6192            // Ensure that any processes we had put on hold are now started
6193            // up.
6194            final int NP = mProcessesOnHold.size();
6195            if (NP > 0) {
6196                ArrayList<ProcessRecord> procs =
6197                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6198                for (int ip=0; ip<NP; ip++) {
6199                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6200                            + procs.get(ip));
6201                    startProcessLocked(procs.get(ip), "on-hold", null);
6202                }
6203            }
6204
6205            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6206                // Start looking for apps that are abusing wake locks.
6207                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6208                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6209                // Tell anyone interested that we are done booting!
6210                SystemProperties.set("sys.boot_completed", "1");
6211                SystemProperties.set("dev.bootcomplete", "1");
6212                for (int i=0; i<mStartedUsers.size(); i++) {
6213                    UserStartedState uss = mStartedUsers.valueAt(i);
6214                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6215                        uss.mState = UserStartedState.STATE_RUNNING;
6216                        final int userId = mStartedUsers.keyAt(i);
6217                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6218                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6219                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6220                        broadcastIntentLocked(null, null, intent, null,
6221                                new IIntentReceiver.Stub() {
6222                                    @Override
6223                                    public void performReceive(Intent intent, int resultCode,
6224                                            String data, Bundle extras, boolean ordered,
6225                                            boolean sticky, int sendingUser) {
6226                                        synchronized (ActivityManagerService.this) {
6227                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6228                                                    true, false);
6229                                        }
6230                                    }
6231                                },
6232                                0, null, null,
6233                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6234                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6235                                userId);
6236                    }
6237                }
6238                scheduleStartProfilesLocked();
6239            }
6240        }
6241    }
6242
6243    final void ensureBootCompleted() {
6244        boolean booting;
6245        boolean enableScreen;
6246        synchronized (this) {
6247            booting = mBooting;
6248            mBooting = false;
6249            enableScreen = !mBooted;
6250            mBooted = true;
6251        }
6252
6253        if (booting) {
6254            finishBooting();
6255        }
6256
6257        if (enableScreen) {
6258            enableScreenAfterBoot();
6259        }
6260    }
6261
6262    @Override
6263    public final void activityResumed(IBinder token) {
6264        final long origId = Binder.clearCallingIdentity();
6265        synchronized(this) {
6266            ActivityStack stack = ActivityRecord.getStackLocked(token);
6267            if (stack != null) {
6268                ActivityRecord.activityResumedLocked(token);
6269            }
6270        }
6271        Binder.restoreCallingIdentity(origId);
6272    }
6273
6274    @Override
6275    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6276        final long origId = Binder.clearCallingIdentity();
6277        synchronized(this) {
6278            ActivityStack stack = ActivityRecord.getStackLocked(token);
6279            if (stack != null) {
6280                stack.activityPausedLocked(token, false, persistentState);
6281            }
6282        }
6283        Binder.restoreCallingIdentity(origId);
6284    }
6285
6286    @Override
6287    public final void activityStopped(IBinder token, Bundle icicle,
6288            PersistableBundle persistentState, CharSequence description) {
6289        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6290
6291        // Refuse possible leaked file descriptors
6292        if (icicle != null && icicle.hasFileDescriptors()) {
6293            throw new IllegalArgumentException("File descriptors passed in Bundle");
6294        }
6295
6296        final long origId = Binder.clearCallingIdentity();
6297
6298        synchronized (this) {
6299            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6300            if (r != null) {
6301                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6302            }
6303        }
6304
6305        trimApplications();
6306
6307        Binder.restoreCallingIdentity(origId);
6308    }
6309
6310    @Override
6311    public final void activityDestroyed(IBinder token) {
6312        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6313        synchronized (this) {
6314            ActivityStack stack = ActivityRecord.getStackLocked(token);
6315            if (stack != null) {
6316                stack.activityDestroyedLocked(token);
6317            }
6318        }
6319    }
6320
6321    @Override
6322    public final void backgroundResourcesReleased(IBinder token) {
6323        final long origId = Binder.clearCallingIdentity();
6324        try {
6325            synchronized (this) {
6326                ActivityStack stack = ActivityRecord.getStackLocked(token);
6327                if (stack != null) {
6328                    stack.backgroundResourcesReleased(token);
6329                }
6330            }
6331        } finally {
6332            Binder.restoreCallingIdentity(origId);
6333        }
6334    }
6335
6336    @Override
6337    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6338        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6339    }
6340
6341    @Override
6342    public final void notifyEnterAnimationComplete(IBinder token) {
6343        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6344    }
6345
6346    @Override
6347    public String getCallingPackage(IBinder token) {
6348        synchronized (this) {
6349            ActivityRecord r = getCallingRecordLocked(token);
6350            return r != null ? r.info.packageName : null;
6351        }
6352    }
6353
6354    @Override
6355    public ComponentName getCallingActivity(IBinder token) {
6356        synchronized (this) {
6357            ActivityRecord r = getCallingRecordLocked(token);
6358            return r != null ? r.intent.getComponent() : null;
6359        }
6360    }
6361
6362    private ActivityRecord getCallingRecordLocked(IBinder token) {
6363        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6364        if (r == null) {
6365            return null;
6366        }
6367        return r.resultTo;
6368    }
6369
6370    @Override
6371    public ComponentName getActivityClassForToken(IBinder token) {
6372        synchronized(this) {
6373            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6374            if (r == null) {
6375                return null;
6376            }
6377            return r.intent.getComponent();
6378        }
6379    }
6380
6381    @Override
6382    public String getPackageForToken(IBinder token) {
6383        synchronized(this) {
6384            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6385            if (r == null) {
6386                return null;
6387            }
6388            return r.packageName;
6389        }
6390    }
6391
6392    @Override
6393    public IIntentSender getIntentSender(int type,
6394            String packageName, IBinder token, String resultWho,
6395            int requestCode, Intent[] intents, String[] resolvedTypes,
6396            int flags, Bundle options, int userId) {
6397        enforceNotIsolatedCaller("getIntentSender");
6398        // Refuse possible leaked file descriptors
6399        if (intents != null) {
6400            if (intents.length < 1) {
6401                throw new IllegalArgumentException("Intents array length must be >= 1");
6402            }
6403            for (int i=0; i<intents.length; i++) {
6404                Intent intent = intents[i];
6405                if (intent != null) {
6406                    if (intent.hasFileDescriptors()) {
6407                        throw new IllegalArgumentException("File descriptors passed in Intent");
6408                    }
6409                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6410                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6411                        throw new IllegalArgumentException(
6412                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6413                    }
6414                    intents[i] = new Intent(intent);
6415                }
6416            }
6417            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6418                throw new IllegalArgumentException(
6419                        "Intent array length does not match resolvedTypes length");
6420            }
6421        }
6422        if (options != null) {
6423            if (options.hasFileDescriptors()) {
6424                throw new IllegalArgumentException("File descriptors passed in options");
6425            }
6426        }
6427
6428        synchronized(this) {
6429            int callingUid = Binder.getCallingUid();
6430            int origUserId = userId;
6431            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6432                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6433                    ALLOW_NON_FULL, "getIntentSender", null);
6434            if (origUserId == UserHandle.USER_CURRENT) {
6435                // We don't want to evaluate this until the pending intent is
6436                // actually executed.  However, we do want to always do the
6437                // security checking for it above.
6438                userId = UserHandle.USER_CURRENT;
6439            }
6440            try {
6441                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6442                    int uid = AppGlobals.getPackageManager()
6443                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6444                    if (!UserHandle.isSameApp(callingUid, uid)) {
6445                        String msg = "Permission Denial: getIntentSender() from pid="
6446                            + Binder.getCallingPid()
6447                            + ", uid=" + Binder.getCallingUid()
6448                            + ", (need uid=" + uid + ")"
6449                            + " is not allowed to send as package " + packageName;
6450                        Slog.w(TAG, msg);
6451                        throw new SecurityException(msg);
6452                    }
6453                }
6454
6455                return getIntentSenderLocked(type, packageName, callingUid, userId,
6456                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6457
6458            } catch (RemoteException e) {
6459                throw new SecurityException(e);
6460            }
6461        }
6462    }
6463
6464    IIntentSender getIntentSenderLocked(int type, String packageName,
6465            int callingUid, int userId, IBinder token, String resultWho,
6466            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6467            Bundle options) {
6468        if (DEBUG_MU)
6469            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6470        ActivityRecord activity = null;
6471        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6472            activity = ActivityRecord.isInStackLocked(token);
6473            if (activity == null) {
6474                return null;
6475            }
6476            if (activity.finishing) {
6477                return null;
6478            }
6479        }
6480
6481        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6482        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6483        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6484        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6485                |PendingIntent.FLAG_UPDATE_CURRENT);
6486
6487        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6488                type, packageName, activity, resultWho,
6489                requestCode, intents, resolvedTypes, flags, options, userId);
6490        WeakReference<PendingIntentRecord> ref;
6491        ref = mIntentSenderRecords.get(key);
6492        PendingIntentRecord rec = ref != null ? ref.get() : null;
6493        if (rec != null) {
6494            if (!cancelCurrent) {
6495                if (updateCurrent) {
6496                    if (rec.key.requestIntent != null) {
6497                        rec.key.requestIntent.replaceExtras(intents != null ?
6498                                intents[intents.length - 1] : null);
6499                    }
6500                    if (intents != null) {
6501                        intents[intents.length-1] = rec.key.requestIntent;
6502                        rec.key.allIntents = intents;
6503                        rec.key.allResolvedTypes = resolvedTypes;
6504                    } else {
6505                        rec.key.allIntents = null;
6506                        rec.key.allResolvedTypes = null;
6507                    }
6508                }
6509                return rec;
6510            }
6511            rec.canceled = true;
6512            mIntentSenderRecords.remove(key);
6513        }
6514        if (noCreate) {
6515            return rec;
6516        }
6517        rec = new PendingIntentRecord(this, key, callingUid);
6518        mIntentSenderRecords.put(key, rec.ref);
6519        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6520            if (activity.pendingResults == null) {
6521                activity.pendingResults
6522                        = new HashSet<WeakReference<PendingIntentRecord>>();
6523            }
6524            activity.pendingResults.add(rec.ref);
6525        }
6526        return rec;
6527    }
6528
6529    @Override
6530    public void cancelIntentSender(IIntentSender sender) {
6531        if (!(sender instanceof PendingIntentRecord)) {
6532            return;
6533        }
6534        synchronized(this) {
6535            PendingIntentRecord rec = (PendingIntentRecord)sender;
6536            try {
6537                int uid = AppGlobals.getPackageManager()
6538                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6539                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6540                    String msg = "Permission Denial: cancelIntentSender() from pid="
6541                        + Binder.getCallingPid()
6542                        + ", uid=" + Binder.getCallingUid()
6543                        + " is not allowed to cancel packges "
6544                        + rec.key.packageName;
6545                    Slog.w(TAG, msg);
6546                    throw new SecurityException(msg);
6547                }
6548            } catch (RemoteException e) {
6549                throw new SecurityException(e);
6550            }
6551            cancelIntentSenderLocked(rec, true);
6552        }
6553    }
6554
6555    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6556        rec.canceled = true;
6557        mIntentSenderRecords.remove(rec.key);
6558        if (cleanActivity && rec.key.activity != null) {
6559            rec.key.activity.pendingResults.remove(rec.ref);
6560        }
6561    }
6562
6563    @Override
6564    public String getPackageForIntentSender(IIntentSender pendingResult) {
6565        if (!(pendingResult instanceof PendingIntentRecord)) {
6566            return null;
6567        }
6568        try {
6569            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6570            return res.key.packageName;
6571        } catch (ClassCastException e) {
6572        }
6573        return null;
6574    }
6575
6576    @Override
6577    public int getUidForIntentSender(IIntentSender sender) {
6578        if (sender instanceof PendingIntentRecord) {
6579            try {
6580                PendingIntentRecord res = (PendingIntentRecord)sender;
6581                return res.uid;
6582            } catch (ClassCastException e) {
6583            }
6584        }
6585        return -1;
6586    }
6587
6588    @Override
6589    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6590        if (!(pendingResult instanceof PendingIntentRecord)) {
6591            return false;
6592        }
6593        try {
6594            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6595            if (res.key.allIntents == null) {
6596                return false;
6597            }
6598            for (int i=0; i<res.key.allIntents.length; i++) {
6599                Intent intent = res.key.allIntents[i];
6600                if (intent.getPackage() != null && intent.getComponent() != null) {
6601                    return false;
6602                }
6603            }
6604            return true;
6605        } catch (ClassCastException e) {
6606        }
6607        return false;
6608    }
6609
6610    @Override
6611    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6612        if (!(pendingResult instanceof PendingIntentRecord)) {
6613            return false;
6614        }
6615        try {
6616            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6617            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6618                return true;
6619            }
6620            return false;
6621        } catch (ClassCastException e) {
6622        }
6623        return false;
6624    }
6625
6626    @Override
6627    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6628        if (!(pendingResult instanceof PendingIntentRecord)) {
6629            return null;
6630        }
6631        try {
6632            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6633            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6634        } catch (ClassCastException e) {
6635        }
6636        return null;
6637    }
6638
6639    @Override
6640    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6641        if (!(pendingResult instanceof PendingIntentRecord)) {
6642            return null;
6643        }
6644        try {
6645            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6646            Intent intent = res.key.requestIntent;
6647            if (intent != null) {
6648                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6649                        || res.lastTagPrefix.equals(prefix))) {
6650                    return res.lastTag;
6651                }
6652                res.lastTagPrefix = prefix;
6653                StringBuilder sb = new StringBuilder(128);
6654                if (prefix != null) {
6655                    sb.append(prefix);
6656                }
6657                if (intent.getAction() != null) {
6658                    sb.append(intent.getAction());
6659                } else if (intent.getComponent() != null) {
6660                    intent.getComponent().appendShortString(sb);
6661                } else {
6662                    sb.append("?");
6663                }
6664                return res.lastTag = sb.toString();
6665            }
6666        } catch (ClassCastException e) {
6667        }
6668        return null;
6669    }
6670
6671    @Override
6672    public void setProcessLimit(int max) {
6673        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6674                "setProcessLimit()");
6675        synchronized (this) {
6676            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6677            mProcessLimitOverride = max;
6678        }
6679        trimApplications();
6680    }
6681
6682    @Override
6683    public int getProcessLimit() {
6684        synchronized (this) {
6685            return mProcessLimitOverride;
6686        }
6687    }
6688
6689    void foregroundTokenDied(ForegroundToken token) {
6690        synchronized (ActivityManagerService.this) {
6691            synchronized (mPidsSelfLocked) {
6692                ForegroundToken cur
6693                    = mForegroundProcesses.get(token.pid);
6694                if (cur != token) {
6695                    return;
6696                }
6697                mForegroundProcesses.remove(token.pid);
6698                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6699                if (pr == null) {
6700                    return;
6701                }
6702                pr.forcingToForeground = null;
6703                updateProcessForegroundLocked(pr, false, false);
6704            }
6705            updateOomAdjLocked();
6706        }
6707    }
6708
6709    @Override
6710    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6711        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6712                "setProcessForeground()");
6713        synchronized(this) {
6714            boolean changed = false;
6715
6716            synchronized (mPidsSelfLocked) {
6717                ProcessRecord pr = mPidsSelfLocked.get(pid);
6718                if (pr == null && isForeground) {
6719                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6720                    return;
6721                }
6722                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6723                if (oldToken != null) {
6724                    oldToken.token.unlinkToDeath(oldToken, 0);
6725                    mForegroundProcesses.remove(pid);
6726                    if (pr != null) {
6727                        pr.forcingToForeground = null;
6728                    }
6729                    changed = true;
6730                }
6731                if (isForeground && token != null) {
6732                    ForegroundToken newToken = new ForegroundToken() {
6733                        @Override
6734                        public void binderDied() {
6735                            foregroundTokenDied(this);
6736                        }
6737                    };
6738                    newToken.pid = pid;
6739                    newToken.token = token;
6740                    try {
6741                        token.linkToDeath(newToken, 0);
6742                        mForegroundProcesses.put(pid, newToken);
6743                        pr.forcingToForeground = token;
6744                        changed = true;
6745                    } catch (RemoteException e) {
6746                        // If the process died while doing this, we will later
6747                        // do the cleanup with the process death link.
6748                    }
6749                }
6750            }
6751
6752            if (changed) {
6753                updateOomAdjLocked();
6754            }
6755        }
6756    }
6757
6758    // =========================================================
6759    // PERMISSIONS
6760    // =========================================================
6761
6762    static class PermissionController extends IPermissionController.Stub {
6763        ActivityManagerService mActivityManagerService;
6764        PermissionController(ActivityManagerService activityManagerService) {
6765            mActivityManagerService = activityManagerService;
6766        }
6767
6768        @Override
6769        public boolean checkPermission(String permission, int pid, int uid) {
6770            return mActivityManagerService.checkPermission(permission, pid,
6771                    uid) == PackageManager.PERMISSION_GRANTED;
6772        }
6773    }
6774
6775    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6776        @Override
6777        public int checkComponentPermission(String permission, int pid, int uid,
6778                int owningUid, boolean exported) {
6779            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6780                    owningUid, exported);
6781        }
6782
6783        @Override
6784        public Object getAMSLock() {
6785            return ActivityManagerService.this;
6786        }
6787    }
6788
6789    /**
6790     * This can be called with or without the global lock held.
6791     */
6792    int checkComponentPermission(String permission, int pid, int uid,
6793            int owningUid, boolean exported) {
6794        // We might be performing an operation on behalf of an indirect binder
6795        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6796        // client identity accordingly before proceeding.
6797        Identity tlsIdentity = sCallerIdentity.get();
6798        if (tlsIdentity != null) {
6799            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6800                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6801            uid = tlsIdentity.uid;
6802            pid = tlsIdentity.pid;
6803        }
6804
6805        if (pid == MY_PID) {
6806            return PackageManager.PERMISSION_GRANTED;
6807        }
6808
6809        return ActivityManager.checkComponentPermission(permission, uid,
6810                owningUid, exported);
6811    }
6812
6813    /**
6814     * As the only public entry point for permissions checking, this method
6815     * can enforce the semantic that requesting a check on a null global
6816     * permission is automatically denied.  (Internally a null permission
6817     * string is used when calling {@link #checkComponentPermission} in cases
6818     * when only uid-based security is needed.)
6819     *
6820     * This can be called with or without the global lock held.
6821     */
6822    @Override
6823    public int checkPermission(String permission, int pid, int uid) {
6824        if (permission == null) {
6825            return PackageManager.PERMISSION_DENIED;
6826        }
6827        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6828    }
6829
6830    /**
6831     * Binder IPC calls go through the public entry point.
6832     * This can be called with or without the global lock held.
6833     */
6834    int checkCallingPermission(String permission) {
6835        return checkPermission(permission,
6836                Binder.getCallingPid(),
6837                UserHandle.getAppId(Binder.getCallingUid()));
6838    }
6839
6840    /**
6841     * This can be called with or without the global lock held.
6842     */
6843    void enforceCallingPermission(String permission, String func) {
6844        if (checkCallingPermission(permission)
6845                == PackageManager.PERMISSION_GRANTED) {
6846            return;
6847        }
6848
6849        String msg = "Permission Denial: " + func + " from pid="
6850                + Binder.getCallingPid()
6851                + ", uid=" + Binder.getCallingUid()
6852                + " requires " + permission;
6853        Slog.w(TAG, msg);
6854        throw new SecurityException(msg);
6855    }
6856
6857    /**
6858     * Determine if UID is holding permissions required to access {@link Uri} in
6859     * the given {@link ProviderInfo}. Final permission checking is always done
6860     * in {@link ContentProvider}.
6861     */
6862    private final boolean checkHoldingPermissionsLocked(
6863            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6864        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6865                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6866        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6867            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6868                    != PERMISSION_GRANTED) {
6869                return false;
6870            }
6871        }
6872        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6873    }
6874
6875    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6876            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6877        if (pi.applicationInfo.uid == uid) {
6878            return true;
6879        } else if (!pi.exported) {
6880            return false;
6881        }
6882
6883        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6884        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6885        try {
6886            // check if target holds top-level <provider> permissions
6887            if (!readMet && pi.readPermission != null && considerUidPermissions
6888                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6889                readMet = true;
6890            }
6891            if (!writeMet && pi.writePermission != null && considerUidPermissions
6892                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6893                writeMet = true;
6894            }
6895
6896            // track if unprotected read/write is allowed; any denied
6897            // <path-permission> below removes this ability
6898            boolean allowDefaultRead = pi.readPermission == null;
6899            boolean allowDefaultWrite = pi.writePermission == null;
6900
6901            // check if target holds any <path-permission> that match uri
6902            final PathPermission[] pps = pi.pathPermissions;
6903            if (pps != null) {
6904                final String path = grantUri.uri.getPath();
6905                int i = pps.length;
6906                while (i > 0 && (!readMet || !writeMet)) {
6907                    i--;
6908                    PathPermission pp = pps[i];
6909                    if (pp.match(path)) {
6910                        if (!readMet) {
6911                            final String pprperm = pp.getReadPermission();
6912                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6913                                    + pprperm + " for " + pp.getPath()
6914                                    + ": match=" + pp.match(path)
6915                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6916                            if (pprperm != null) {
6917                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6918                                        == PERMISSION_GRANTED) {
6919                                    readMet = true;
6920                                } else {
6921                                    allowDefaultRead = false;
6922                                }
6923                            }
6924                        }
6925                        if (!writeMet) {
6926                            final String ppwperm = pp.getWritePermission();
6927                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6928                                    + ppwperm + " for " + pp.getPath()
6929                                    + ": match=" + pp.match(path)
6930                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6931                            if (ppwperm != null) {
6932                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6933                                        == PERMISSION_GRANTED) {
6934                                    writeMet = true;
6935                                } else {
6936                                    allowDefaultWrite = false;
6937                                }
6938                            }
6939                        }
6940                    }
6941                }
6942            }
6943
6944            // grant unprotected <provider> read/write, if not blocked by
6945            // <path-permission> above
6946            if (allowDefaultRead) readMet = true;
6947            if (allowDefaultWrite) writeMet = true;
6948
6949        } catch (RemoteException e) {
6950            return false;
6951        }
6952
6953        return readMet && writeMet;
6954    }
6955
6956    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6957        ProviderInfo pi = null;
6958        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6959        if (cpr != null) {
6960            pi = cpr.info;
6961        } else {
6962            try {
6963                pi = AppGlobals.getPackageManager().resolveContentProvider(
6964                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6965            } catch (RemoteException ex) {
6966            }
6967        }
6968        return pi;
6969    }
6970
6971    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6972        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6973        if (targetUris != null) {
6974            return targetUris.get(grantUri);
6975        }
6976        return null;
6977    }
6978
6979    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6980            String targetPkg, int targetUid, GrantUri grantUri) {
6981        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6982        if (targetUris == null) {
6983            targetUris = Maps.newArrayMap();
6984            mGrantedUriPermissions.put(targetUid, targetUris);
6985        }
6986
6987        UriPermission perm = targetUris.get(grantUri);
6988        if (perm == null) {
6989            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6990            targetUris.put(grantUri, perm);
6991        }
6992
6993        return perm;
6994    }
6995
6996    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6997            final int modeFlags) {
6998        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6999        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7000                : UriPermission.STRENGTH_OWNED;
7001
7002        // Root gets to do everything.
7003        if (uid == 0) {
7004            return true;
7005        }
7006
7007        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7008        if (perms == null) return false;
7009
7010        // First look for exact match
7011        final UriPermission exactPerm = perms.get(grantUri);
7012        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7013            return true;
7014        }
7015
7016        // No exact match, look for prefixes
7017        final int N = perms.size();
7018        for (int i = 0; i < N; i++) {
7019            final UriPermission perm = perms.valueAt(i);
7020            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7021                    && perm.getStrength(modeFlags) >= minStrength) {
7022                return true;
7023            }
7024        }
7025
7026        return false;
7027    }
7028
7029    /**
7030     * @param uri This uri must NOT contain an embedded userId.
7031     * @param userId The userId in which the uri is to be resolved.
7032     */
7033    @Override
7034    public int checkUriPermission(Uri uri, int pid, int uid,
7035            final int modeFlags, int userId) {
7036        enforceNotIsolatedCaller("checkUriPermission");
7037
7038        // Another redirected-binder-call permissions check as in
7039        // {@link checkComponentPermission}.
7040        Identity tlsIdentity = sCallerIdentity.get();
7041        if (tlsIdentity != null) {
7042            uid = tlsIdentity.uid;
7043            pid = tlsIdentity.pid;
7044        }
7045
7046        // Our own process gets to do everything.
7047        if (pid == MY_PID) {
7048            return PackageManager.PERMISSION_GRANTED;
7049        }
7050        synchronized (this) {
7051            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7052                    ? PackageManager.PERMISSION_GRANTED
7053                    : PackageManager.PERMISSION_DENIED;
7054        }
7055    }
7056
7057    /**
7058     * Check if the targetPkg can be granted permission to access uri by
7059     * the callingUid using the given modeFlags.  Throws a security exception
7060     * if callingUid is not allowed to do this.  Returns the uid of the target
7061     * if the URI permission grant should be performed; returns -1 if it is not
7062     * needed (for example targetPkg already has permission to access the URI).
7063     * If you already know the uid of the target, you can supply it in
7064     * lastTargetUid else set that to -1.
7065     */
7066    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7067            final int modeFlags, int lastTargetUid) {
7068        if (!Intent.isAccessUriMode(modeFlags)) {
7069            return -1;
7070        }
7071
7072        if (targetPkg != null) {
7073            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7074                    "Checking grant " + targetPkg + " permission to " + grantUri);
7075        }
7076
7077        final IPackageManager pm = AppGlobals.getPackageManager();
7078
7079        // If this is not a content: uri, we can't do anything with it.
7080        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7081            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7082                    "Can't grant URI permission for non-content URI: " + grantUri);
7083            return -1;
7084        }
7085
7086        final String authority = grantUri.uri.getAuthority();
7087        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7088        if (pi == null) {
7089            Slog.w(TAG, "No content provider found for permission check: " +
7090                    grantUri.uri.toSafeString());
7091            return -1;
7092        }
7093
7094        int targetUid = lastTargetUid;
7095        if (targetUid < 0 && targetPkg != null) {
7096            try {
7097                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7098                if (targetUid < 0) {
7099                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7100                            "Can't grant URI permission no uid for: " + targetPkg);
7101                    return -1;
7102                }
7103            } catch (RemoteException ex) {
7104                return -1;
7105            }
7106        }
7107
7108        if (targetUid >= 0) {
7109            // First...  does the target actually need this permission?
7110            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7111                // No need to grant the target this permission.
7112                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7113                        "Target " + targetPkg + " already has full permission to " + grantUri);
7114                return -1;
7115            }
7116        } else {
7117            // First...  there is no target package, so can anyone access it?
7118            boolean allowed = pi.exported;
7119            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7120                if (pi.readPermission != null) {
7121                    allowed = false;
7122                }
7123            }
7124            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7125                if (pi.writePermission != null) {
7126                    allowed = false;
7127                }
7128            }
7129            if (allowed) {
7130                return -1;
7131            }
7132        }
7133
7134        /* There is a special cross user grant if:
7135         * - The target is on another user.
7136         * - Apps on the current user can access the uri without any uid permissions.
7137         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7138         * grant uri permissions.
7139         */
7140        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7141                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7142                modeFlags, false /*without considering the uid permissions*/);
7143
7144        // Second...  is the provider allowing granting of URI permissions?
7145        if (!specialCrossUserGrant) {
7146            if (!pi.grantUriPermissions) {
7147                throw new SecurityException("Provider " + pi.packageName
7148                        + "/" + pi.name
7149                        + " does not allow granting of Uri permissions (uri "
7150                        + grantUri + ")");
7151            }
7152            if (pi.uriPermissionPatterns != null) {
7153                final int N = pi.uriPermissionPatterns.length;
7154                boolean allowed = false;
7155                for (int i=0; i<N; i++) {
7156                    if (pi.uriPermissionPatterns[i] != null
7157                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7158                        allowed = true;
7159                        break;
7160                    }
7161                }
7162                if (!allowed) {
7163                    throw new SecurityException("Provider " + pi.packageName
7164                            + "/" + pi.name
7165                            + " does not allow granting of permission to path of Uri "
7166                            + grantUri);
7167                }
7168            }
7169        }
7170
7171        // Third...  does the caller itself have permission to access
7172        // this uri?
7173        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7174            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7175                // Require they hold a strong enough Uri permission
7176                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7177                    throw new SecurityException("Uid " + callingUid
7178                            + " does not have permission to uri " + grantUri);
7179                }
7180            }
7181        }
7182        return targetUid;
7183    }
7184
7185    /**
7186     * @param uri This uri must NOT contain an embedded userId.
7187     * @param userId The userId in which the uri is to be resolved.
7188     */
7189    @Override
7190    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7191            final int modeFlags, int userId) {
7192        enforceNotIsolatedCaller("checkGrantUriPermission");
7193        synchronized(this) {
7194            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7195                    new GrantUri(userId, uri, false), modeFlags, -1);
7196        }
7197    }
7198
7199    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7200            final int modeFlags, UriPermissionOwner owner) {
7201        if (!Intent.isAccessUriMode(modeFlags)) {
7202            return;
7203        }
7204
7205        // So here we are: the caller has the assumed permission
7206        // to the uri, and the target doesn't.  Let's now give this to
7207        // the target.
7208
7209        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7210                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7211
7212        final String authority = grantUri.uri.getAuthority();
7213        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7214        if (pi == null) {
7215            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7216            return;
7217        }
7218
7219        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7220            grantUri.prefix = true;
7221        }
7222        final UriPermission perm = findOrCreateUriPermissionLocked(
7223                pi.packageName, targetPkg, targetUid, grantUri);
7224        perm.grantModes(modeFlags, owner);
7225    }
7226
7227    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7228            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7229        if (targetPkg == null) {
7230            throw new NullPointerException("targetPkg");
7231        }
7232        int targetUid;
7233        final IPackageManager pm = AppGlobals.getPackageManager();
7234        try {
7235            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7236        } catch (RemoteException ex) {
7237            return;
7238        }
7239
7240        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7241                targetUid);
7242        if (targetUid < 0) {
7243            return;
7244        }
7245
7246        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7247                owner);
7248    }
7249
7250    static class NeededUriGrants extends ArrayList<GrantUri> {
7251        final String targetPkg;
7252        final int targetUid;
7253        final int flags;
7254
7255        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7256            this.targetPkg = targetPkg;
7257            this.targetUid = targetUid;
7258            this.flags = flags;
7259        }
7260    }
7261
7262    /**
7263     * Like checkGrantUriPermissionLocked, but takes an Intent.
7264     */
7265    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7266            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7267        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7268                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7269                + " clip=" + (intent != null ? intent.getClipData() : null)
7270                + " from " + intent + "; flags=0x"
7271                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7272
7273        if (targetPkg == null) {
7274            throw new NullPointerException("targetPkg");
7275        }
7276
7277        if (intent == null) {
7278            return null;
7279        }
7280        Uri data = intent.getData();
7281        ClipData clip = intent.getClipData();
7282        if (data == null && clip == null) {
7283            return null;
7284        }
7285        // Default userId for uris in the intent (if they don't specify it themselves)
7286        int contentUserHint = intent.getContentUserHint();
7287        if (contentUserHint == UserHandle.USER_CURRENT) {
7288            contentUserHint = UserHandle.getUserId(callingUid);
7289        }
7290        final IPackageManager pm = AppGlobals.getPackageManager();
7291        int targetUid;
7292        if (needed != null) {
7293            targetUid = needed.targetUid;
7294        } else {
7295            try {
7296                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7297            } catch (RemoteException ex) {
7298                return null;
7299            }
7300            if (targetUid < 0) {
7301                if (DEBUG_URI_PERMISSION) {
7302                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7303                            + " on user " + targetUserId);
7304                }
7305                return null;
7306            }
7307        }
7308        if (data != null) {
7309            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7310            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7311                    targetUid);
7312            if (targetUid > 0) {
7313                if (needed == null) {
7314                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7315                }
7316                needed.add(grantUri);
7317            }
7318        }
7319        if (clip != null) {
7320            for (int i=0; i<clip.getItemCount(); i++) {
7321                Uri uri = clip.getItemAt(i).getUri();
7322                if (uri != null) {
7323                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7324                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7325                            targetUid);
7326                    if (targetUid > 0) {
7327                        if (needed == null) {
7328                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7329                        }
7330                        needed.add(grantUri);
7331                    }
7332                } else {
7333                    Intent clipIntent = clip.getItemAt(i).getIntent();
7334                    if (clipIntent != null) {
7335                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7336                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7337                        if (newNeeded != null) {
7338                            needed = newNeeded;
7339                        }
7340                    }
7341                }
7342            }
7343        }
7344
7345        return needed;
7346    }
7347
7348    /**
7349     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7350     */
7351    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7352            UriPermissionOwner owner) {
7353        if (needed != null) {
7354            for (int i=0; i<needed.size(); i++) {
7355                GrantUri grantUri = needed.get(i);
7356                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7357                        grantUri, needed.flags, owner);
7358            }
7359        }
7360    }
7361
7362    void grantUriPermissionFromIntentLocked(int callingUid,
7363            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7364        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7365                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7366        if (needed == null) {
7367            return;
7368        }
7369
7370        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7371    }
7372
7373    /**
7374     * @param uri This uri must NOT contain an embedded userId.
7375     * @param userId The userId in which the uri is to be resolved.
7376     */
7377    @Override
7378    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7379            final int modeFlags, int userId) {
7380        enforceNotIsolatedCaller("grantUriPermission");
7381        GrantUri grantUri = new GrantUri(userId, uri, false);
7382        synchronized(this) {
7383            final ProcessRecord r = getRecordForAppLocked(caller);
7384            if (r == null) {
7385                throw new SecurityException("Unable to find app for caller "
7386                        + caller
7387                        + " when granting permission to uri " + grantUri);
7388            }
7389            if (targetPkg == null) {
7390                throw new IllegalArgumentException("null target");
7391            }
7392            if (grantUri == null) {
7393                throw new IllegalArgumentException("null uri");
7394            }
7395
7396            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7397                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7398                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7399                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7400
7401            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7402                    UserHandle.getUserId(r.uid));
7403        }
7404    }
7405
7406    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7407        if (perm.modeFlags == 0) {
7408            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7409                    perm.targetUid);
7410            if (perms != null) {
7411                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7412                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7413
7414                perms.remove(perm.uri);
7415                if (perms.isEmpty()) {
7416                    mGrantedUriPermissions.remove(perm.targetUid);
7417                }
7418            }
7419        }
7420    }
7421
7422    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7423        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7424
7425        final IPackageManager pm = AppGlobals.getPackageManager();
7426        final String authority = grantUri.uri.getAuthority();
7427        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7428        if (pi == null) {
7429            Slog.w(TAG, "No content provider found for permission revoke: "
7430                    + grantUri.toSafeString());
7431            return;
7432        }
7433
7434        // Does the caller have this permission on the URI?
7435        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7436            // Right now, if you are not the original owner of the permission,
7437            // you are not allowed to revoke it.
7438            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7439                throw new SecurityException("Uid " + callingUid
7440                        + " does not have permission to uri " + grantUri);
7441            //}
7442        }
7443
7444        boolean persistChanged = false;
7445
7446        // Go through all of the permissions and remove any that match.
7447        int N = mGrantedUriPermissions.size();
7448        for (int i = 0; i < N; i++) {
7449            final int targetUid = mGrantedUriPermissions.keyAt(i);
7450            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7451
7452            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7453                final UriPermission perm = it.next();
7454                if (perm.uri.sourceUserId == grantUri.sourceUserId
7455                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7456                    if (DEBUG_URI_PERMISSION)
7457                        Slog.v(TAG,
7458                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7459                    persistChanged |= perm.revokeModes(
7460                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7461                    if (perm.modeFlags == 0) {
7462                        it.remove();
7463                    }
7464                }
7465            }
7466
7467            if (perms.isEmpty()) {
7468                mGrantedUriPermissions.remove(targetUid);
7469                N--;
7470                i--;
7471            }
7472        }
7473
7474        if (persistChanged) {
7475            schedulePersistUriGrants();
7476        }
7477    }
7478
7479    /**
7480     * @param uri This uri must NOT contain an embedded userId.
7481     * @param userId The userId in which the uri is to be resolved.
7482     */
7483    @Override
7484    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7485            int userId) {
7486        enforceNotIsolatedCaller("revokeUriPermission");
7487        synchronized(this) {
7488            final ProcessRecord r = getRecordForAppLocked(caller);
7489            if (r == null) {
7490                throw new SecurityException("Unable to find app for caller "
7491                        + caller
7492                        + " when revoking permission to uri " + uri);
7493            }
7494            if (uri == null) {
7495                Slog.w(TAG, "revokeUriPermission: null uri");
7496                return;
7497            }
7498
7499            if (!Intent.isAccessUriMode(modeFlags)) {
7500                return;
7501            }
7502
7503            final IPackageManager pm = AppGlobals.getPackageManager();
7504            final String authority = uri.getAuthority();
7505            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7506            if (pi == null) {
7507                Slog.w(TAG, "No content provider found for permission revoke: "
7508                        + uri.toSafeString());
7509                return;
7510            }
7511
7512            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7513        }
7514    }
7515
7516    /**
7517     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7518     * given package.
7519     *
7520     * @param packageName Package name to match, or {@code null} to apply to all
7521     *            packages.
7522     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7523     *            to all users.
7524     * @param persistable If persistable grants should be removed.
7525     */
7526    private void removeUriPermissionsForPackageLocked(
7527            String packageName, int userHandle, boolean persistable) {
7528        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7529            throw new IllegalArgumentException("Must narrow by either package or user");
7530        }
7531
7532        boolean persistChanged = false;
7533
7534        int N = mGrantedUriPermissions.size();
7535        for (int i = 0; i < N; i++) {
7536            final int targetUid = mGrantedUriPermissions.keyAt(i);
7537            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7538
7539            // Only inspect grants matching user
7540            if (userHandle == UserHandle.USER_ALL
7541                    || userHandle == UserHandle.getUserId(targetUid)) {
7542                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7543                    final UriPermission perm = it.next();
7544
7545                    // Only inspect grants matching package
7546                    if (packageName == null || perm.sourcePkg.equals(packageName)
7547                            || perm.targetPkg.equals(packageName)) {
7548                        persistChanged |= perm.revokeModes(
7549                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7550
7551                        // Only remove when no modes remain; any persisted grants
7552                        // will keep this alive.
7553                        if (perm.modeFlags == 0) {
7554                            it.remove();
7555                        }
7556                    }
7557                }
7558
7559                if (perms.isEmpty()) {
7560                    mGrantedUriPermissions.remove(targetUid);
7561                    N--;
7562                    i--;
7563                }
7564            }
7565        }
7566
7567        if (persistChanged) {
7568            schedulePersistUriGrants();
7569        }
7570    }
7571
7572    @Override
7573    public IBinder newUriPermissionOwner(String name) {
7574        enforceNotIsolatedCaller("newUriPermissionOwner");
7575        synchronized(this) {
7576            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7577            return owner.getExternalTokenLocked();
7578        }
7579    }
7580
7581    /**
7582     * @param uri This uri must NOT contain an embedded userId.
7583     * @param sourceUserId The userId in which the uri is to be resolved.
7584     * @param targetUserId The userId of the app that receives the grant.
7585     */
7586    @Override
7587    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7588            final int modeFlags, int sourceUserId, int targetUserId) {
7589        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7590                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7591        synchronized(this) {
7592            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7593            if (owner == null) {
7594                throw new IllegalArgumentException("Unknown owner: " + token);
7595            }
7596            if (fromUid != Binder.getCallingUid()) {
7597                if (Binder.getCallingUid() != Process.myUid()) {
7598                    // Only system code can grant URI permissions on behalf
7599                    // of other users.
7600                    throw new SecurityException("nice try");
7601                }
7602            }
7603            if (targetPkg == null) {
7604                throw new IllegalArgumentException("null target");
7605            }
7606            if (uri == null) {
7607                throw new IllegalArgumentException("null uri");
7608            }
7609
7610            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7611                    modeFlags, owner, targetUserId);
7612        }
7613    }
7614
7615    /**
7616     * @param uri This uri must NOT contain an embedded userId.
7617     * @param userId The userId in which the uri is to be resolved.
7618     */
7619    @Override
7620    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7621        synchronized(this) {
7622            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7623            if (owner == null) {
7624                throw new IllegalArgumentException("Unknown owner: " + token);
7625            }
7626
7627            if (uri == null) {
7628                owner.removeUriPermissionsLocked(mode);
7629            } else {
7630                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7631            }
7632        }
7633    }
7634
7635    private void schedulePersistUriGrants() {
7636        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7637            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7638                    10 * DateUtils.SECOND_IN_MILLIS);
7639        }
7640    }
7641
7642    private void writeGrantedUriPermissions() {
7643        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7644
7645        // Snapshot permissions so we can persist without lock
7646        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7647        synchronized (this) {
7648            final int size = mGrantedUriPermissions.size();
7649            for (int i = 0; i < size; i++) {
7650                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7651                for (UriPermission perm : perms.values()) {
7652                    if (perm.persistedModeFlags != 0) {
7653                        persist.add(perm.snapshot());
7654                    }
7655                }
7656            }
7657        }
7658
7659        FileOutputStream fos = null;
7660        try {
7661            fos = mGrantFile.startWrite();
7662
7663            XmlSerializer out = new FastXmlSerializer();
7664            out.setOutput(fos, "utf-8");
7665            out.startDocument(null, true);
7666            out.startTag(null, TAG_URI_GRANTS);
7667            for (UriPermission.Snapshot perm : persist) {
7668                out.startTag(null, TAG_URI_GRANT);
7669                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7670                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7671                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7672                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7673                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7674                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7675                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7676                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7677                out.endTag(null, TAG_URI_GRANT);
7678            }
7679            out.endTag(null, TAG_URI_GRANTS);
7680            out.endDocument();
7681
7682            mGrantFile.finishWrite(fos);
7683        } catch (IOException e) {
7684            if (fos != null) {
7685                mGrantFile.failWrite(fos);
7686            }
7687        }
7688    }
7689
7690    private void readGrantedUriPermissionsLocked() {
7691        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7692
7693        final long now = System.currentTimeMillis();
7694
7695        FileInputStream fis = null;
7696        try {
7697            fis = mGrantFile.openRead();
7698            final XmlPullParser in = Xml.newPullParser();
7699            in.setInput(fis, null);
7700
7701            int type;
7702            while ((type = in.next()) != END_DOCUMENT) {
7703                final String tag = in.getName();
7704                if (type == START_TAG) {
7705                    if (TAG_URI_GRANT.equals(tag)) {
7706                        final int sourceUserId;
7707                        final int targetUserId;
7708                        final int userHandle = readIntAttribute(in,
7709                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7710                        if (userHandle != UserHandle.USER_NULL) {
7711                            // For backwards compatibility.
7712                            sourceUserId = userHandle;
7713                            targetUserId = userHandle;
7714                        } else {
7715                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7716                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7717                        }
7718                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7719                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7720                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7721                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7722                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7723                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7724
7725                        // Sanity check that provider still belongs to source package
7726                        final ProviderInfo pi = getProviderInfoLocked(
7727                                uri.getAuthority(), sourceUserId);
7728                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7729                            int targetUid = -1;
7730                            try {
7731                                targetUid = AppGlobals.getPackageManager()
7732                                        .getPackageUid(targetPkg, targetUserId);
7733                            } catch (RemoteException e) {
7734                            }
7735                            if (targetUid != -1) {
7736                                final UriPermission perm = findOrCreateUriPermissionLocked(
7737                                        sourcePkg, targetPkg, targetUid,
7738                                        new GrantUri(sourceUserId, uri, prefix));
7739                                perm.initPersistedModes(modeFlags, createdTime);
7740                            }
7741                        } else {
7742                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7743                                    + " but instead found " + pi);
7744                        }
7745                    }
7746                }
7747            }
7748        } catch (FileNotFoundException e) {
7749            // Missing grants is okay
7750        } catch (IOException e) {
7751            Log.wtf(TAG, "Failed reading Uri grants", e);
7752        } catch (XmlPullParserException e) {
7753            Log.wtf(TAG, "Failed reading Uri grants", e);
7754        } finally {
7755            IoUtils.closeQuietly(fis);
7756        }
7757    }
7758
7759    /**
7760     * @param uri This uri must NOT contain an embedded userId.
7761     * @param userId The userId in which the uri is to be resolved.
7762     */
7763    @Override
7764    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7765        enforceNotIsolatedCaller("takePersistableUriPermission");
7766
7767        Preconditions.checkFlagsArgument(modeFlags,
7768                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7769
7770        synchronized (this) {
7771            final int callingUid = Binder.getCallingUid();
7772            boolean persistChanged = false;
7773            GrantUri grantUri = new GrantUri(userId, uri, false);
7774
7775            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7776                    new GrantUri(userId, uri, false));
7777            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7778                    new GrantUri(userId, uri, true));
7779
7780            final boolean exactValid = (exactPerm != null)
7781                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7782            final boolean prefixValid = (prefixPerm != null)
7783                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7784
7785            if (!(exactValid || prefixValid)) {
7786                throw new SecurityException("No persistable permission grants found for UID "
7787                        + callingUid + " and Uri " + grantUri.toSafeString());
7788            }
7789
7790            if (exactValid) {
7791                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7792            }
7793            if (prefixValid) {
7794                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7795            }
7796
7797            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7798
7799            if (persistChanged) {
7800                schedulePersistUriGrants();
7801            }
7802        }
7803    }
7804
7805    /**
7806     * @param uri This uri must NOT contain an embedded userId.
7807     * @param userId The userId in which the uri is to be resolved.
7808     */
7809    @Override
7810    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7811        enforceNotIsolatedCaller("releasePersistableUriPermission");
7812
7813        Preconditions.checkFlagsArgument(modeFlags,
7814                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7815
7816        synchronized (this) {
7817            final int callingUid = Binder.getCallingUid();
7818            boolean persistChanged = false;
7819
7820            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7821                    new GrantUri(userId, uri, false));
7822            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7823                    new GrantUri(userId, uri, true));
7824            if (exactPerm == null && prefixPerm == null) {
7825                throw new SecurityException("No permission grants found for UID " + callingUid
7826                        + " and Uri " + uri.toSafeString());
7827            }
7828
7829            if (exactPerm != null) {
7830                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7831                removeUriPermissionIfNeededLocked(exactPerm);
7832            }
7833            if (prefixPerm != null) {
7834                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7835                removeUriPermissionIfNeededLocked(prefixPerm);
7836            }
7837
7838            if (persistChanged) {
7839                schedulePersistUriGrants();
7840            }
7841        }
7842    }
7843
7844    /**
7845     * Prune any older {@link UriPermission} for the given UID until outstanding
7846     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7847     *
7848     * @return if any mutations occured that require persisting.
7849     */
7850    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7851        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7852        if (perms == null) return false;
7853        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7854
7855        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7856        for (UriPermission perm : perms.values()) {
7857            if (perm.persistedModeFlags != 0) {
7858                persisted.add(perm);
7859            }
7860        }
7861
7862        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7863        if (trimCount <= 0) return false;
7864
7865        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7866        for (int i = 0; i < trimCount; i++) {
7867            final UriPermission perm = persisted.get(i);
7868
7869            if (DEBUG_URI_PERMISSION) {
7870                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7871            }
7872
7873            perm.releasePersistableModes(~0);
7874            removeUriPermissionIfNeededLocked(perm);
7875        }
7876
7877        return true;
7878    }
7879
7880    @Override
7881    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7882            String packageName, boolean incoming) {
7883        enforceNotIsolatedCaller("getPersistedUriPermissions");
7884        Preconditions.checkNotNull(packageName, "packageName");
7885
7886        final int callingUid = Binder.getCallingUid();
7887        final IPackageManager pm = AppGlobals.getPackageManager();
7888        try {
7889            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7890            if (packageUid != callingUid) {
7891                throw new SecurityException(
7892                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7893            }
7894        } catch (RemoteException e) {
7895            throw new SecurityException("Failed to verify package name ownership");
7896        }
7897
7898        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7899        synchronized (this) {
7900            if (incoming) {
7901                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7902                        callingUid);
7903                if (perms == null) {
7904                    Slog.w(TAG, "No permission grants found for " + packageName);
7905                } else {
7906                    for (UriPermission perm : perms.values()) {
7907                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7908                            result.add(perm.buildPersistedPublicApiObject());
7909                        }
7910                    }
7911                }
7912            } else {
7913                final int size = mGrantedUriPermissions.size();
7914                for (int i = 0; i < size; i++) {
7915                    final ArrayMap<GrantUri, UriPermission> perms =
7916                            mGrantedUriPermissions.valueAt(i);
7917                    for (UriPermission perm : perms.values()) {
7918                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7919                            result.add(perm.buildPersistedPublicApiObject());
7920                        }
7921                    }
7922                }
7923            }
7924        }
7925        return new ParceledListSlice<android.content.UriPermission>(result);
7926    }
7927
7928    @Override
7929    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7930        synchronized (this) {
7931            ProcessRecord app =
7932                who != null ? getRecordForAppLocked(who) : null;
7933            if (app == null) return;
7934
7935            Message msg = Message.obtain();
7936            msg.what = WAIT_FOR_DEBUGGER_MSG;
7937            msg.obj = app;
7938            msg.arg1 = waiting ? 1 : 0;
7939            mHandler.sendMessage(msg);
7940        }
7941    }
7942
7943    @Override
7944    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7945        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7946        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7947        outInfo.availMem = Process.getFreeMemory();
7948        outInfo.totalMem = Process.getTotalMemory();
7949        outInfo.threshold = homeAppMem;
7950        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7951        outInfo.hiddenAppThreshold = cachedAppMem;
7952        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7953                ProcessList.SERVICE_ADJ);
7954        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7955                ProcessList.VISIBLE_APP_ADJ);
7956        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7957                ProcessList.FOREGROUND_APP_ADJ);
7958    }
7959
7960    // =========================================================
7961    // TASK MANAGEMENT
7962    // =========================================================
7963
7964    @Override
7965    public List<IAppTask> getAppTasks(String callingPackage) {
7966        int callingUid = Binder.getCallingUid();
7967        long ident = Binder.clearCallingIdentity();
7968
7969        synchronized(this) {
7970            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7971            try {
7972                if (localLOGV) Slog.v(TAG, "getAppTasks");
7973
7974                final int N = mRecentTasks.size();
7975                for (int i = 0; i < N; i++) {
7976                    TaskRecord tr = mRecentTasks.get(i);
7977                    // Skip tasks that do not match the caller.  We don't need to verify
7978                    // callingPackage, because we are also limiting to callingUid and know
7979                    // that will limit to the correct security sandbox.
7980                    if (tr.effectiveUid != callingUid) {
7981                        continue;
7982                    }
7983                    Intent intent = tr.getBaseIntent();
7984                    if (intent == null ||
7985                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7986                        continue;
7987                    }
7988                    ActivityManager.RecentTaskInfo taskInfo =
7989                            createRecentTaskInfoFromTaskRecord(tr);
7990                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7991                    list.add(taskImpl);
7992                }
7993            } finally {
7994                Binder.restoreCallingIdentity(ident);
7995            }
7996            return list;
7997        }
7998    }
7999
8000    @Override
8001    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8002        final int callingUid = Binder.getCallingUid();
8003        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8004
8005        synchronized(this) {
8006            if (localLOGV) Slog.v(
8007                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8008
8009            final boolean allowed = checkCallingPermission(
8010                    android.Manifest.permission.GET_TASKS)
8011                    == PackageManager.PERMISSION_GRANTED;
8012            if (!allowed) {
8013                Slog.w(TAG, "getTasks: caller " + callingUid
8014                        + " does not hold GET_TASKS; limiting output");
8015            }
8016
8017            // TODO: Improve with MRU list from all ActivityStacks.
8018            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8019        }
8020
8021        return list;
8022    }
8023
8024    TaskRecord getMostRecentTask() {
8025        return mRecentTasks.get(0);
8026    }
8027
8028    /**
8029     * Creates a new RecentTaskInfo from a TaskRecord.
8030     */
8031    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8032        // Update the task description to reflect any changes in the task stack
8033        tr.updateTaskDescription();
8034
8035        // Compose the recent task info
8036        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8037        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8038        rti.persistentId = tr.taskId;
8039        rti.baseIntent = new Intent(tr.getBaseIntent());
8040        rti.origActivity = tr.origActivity;
8041        rti.description = tr.lastDescription;
8042        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8043        rti.userId = tr.userId;
8044        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8045        rti.firstActiveTime = tr.firstActiveTime;
8046        rti.lastActiveTime = tr.lastActiveTime;
8047        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8048        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8049        return rti;
8050    }
8051
8052    @Override
8053    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8054        final int callingUid = Binder.getCallingUid();
8055        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8056                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8057
8058        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8059        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8060        synchronized (this) {
8061            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8062                    == PackageManager.PERMISSION_GRANTED;
8063            if (!allowed) {
8064                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8065                        + " does not hold GET_TASKS; limiting output");
8066            }
8067            final boolean detailed = checkCallingPermission(
8068                    android.Manifest.permission.GET_DETAILED_TASKS)
8069                    == PackageManager.PERMISSION_GRANTED;
8070
8071            final int N = mRecentTasks.size();
8072            ArrayList<ActivityManager.RecentTaskInfo> res
8073                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8074                            maxNum < N ? maxNum : N);
8075
8076            final Set<Integer> includedUsers;
8077            if (includeProfiles) {
8078                includedUsers = getProfileIdsLocked(userId);
8079            } else {
8080                includedUsers = new HashSet<Integer>();
8081            }
8082            includedUsers.add(Integer.valueOf(userId));
8083
8084            for (int i=0; i<N && maxNum > 0; i++) {
8085                TaskRecord tr = mRecentTasks.get(i);
8086                // Only add calling user or related users recent tasks
8087                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8088                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8089                    continue;
8090                }
8091
8092                // Return the entry if desired by the caller.  We always return
8093                // the first entry, because callers always expect this to be the
8094                // foreground app.  We may filter others if the caller has
8095                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8096                // we should exclude the entry.
8097
8098                if (i == 0
8099                        || withExcluded
8100                        || (tr.intent == null)
8101                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8102                                == 0)) {
8103                    if (!allowed) {
8104                        // If the caller doesn't have the GET_TASKS permission, then only
8105                        // allow them to see a small subset of tasks -- their own and home.
8106                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8107                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8108                            continue;
8109                        }
8110                    }
8111                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8112                        if (tr.stack != null && tr.stack.isHomeStack()) {
8113                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8114                            continue;
8115                        }
8116                    }
8117                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8118                        // Don't include auto remove tasks that are finished or finishing.
8119                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8120                                + tr);
8121                        continue;
8122                    }
8123                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8124                            && !tr.isAvailable) {
8125                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8126                        continue;
8127                    }
8128
8129                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8130                    if (!detailed) {
8131                        rti.baseIntent.replaceExtras((Bundle)null);
8132                    }
8133
8134                    res.add(rti);
8135                    maxNum--;
8136                }
8137            }
8138            return res;
8139        }
8140    }
8141
8142    private TaskRecord recentTaskForIdLocked(int id) {
8143        final int N = mRecentTasks.size();
8144            for (int i=0; i<N; i++) {
8145                TaskRecord tr = mRecentTasks.get(i);
8146                if (tr.taskId == id) {
8147                    return tr;
8148                }
8149            }
8150            return null;
8151    }
8152
8153    @Override
8154    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8155        synchronized (this) {
8156            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8157                    "getTaskThumbnail()");
8158            TaskRecord tr = recentTaskForIdLocked(id);
8159            if (tr != null) {
8160                return tr.getTaskThumbnailLocked();
8161            }
8162        }
8163        return null;
8164    }
8165
8166    @Override
8167    public int addAppTask(IBinder activityToken, Intent intent,
8168            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8169        final int callingUid = Binder.getCallingUid();
8170        final long callingIdent = Binder.clearCallingIdentity();
8171
8172        try {
8173            synchronized (this) {
8174                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8175                if (r == null) {
8176                    throw new IllegalArgumentException("Activity does not exist; token="
8177                            + activityToken);
8178                }
8179                ComponentName comp = intent.getComponent();
8180                if (comp == null) {
8181                    throw new IllegalArgumentException("Intent " + intent
8182                            + " must specify explicit component");
8183                }
8184                if (thumbnail.getWidth() != mThumbnailWidth
8185                        || thumbnail.getHeight() != mThumbnailHeight) {
8186                    throw new IllegalArgumentException("Bad thumbnail size: got "
8187                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8188                            + mThumbnailWidth + "x" + mThumbnailHeight);
8189                }
8190                if (intent.getSelector() != null) {
8191                    intent.setSelector(null);
8192                }
8193                if (intent.getSourceBounds() != null) {
8194                    intent.setSourceBounds(null);
8195                }
8196                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8197                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8198                        // The caller has added this as an auto-remove task...  that makes no
8199                        // sense, so turn off auto-remove.
8200                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8201                    }
8202                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8203                    // Must be a new task.
8204                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8205                }
8206                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8207                    mLastAddedTaskActivity = null;
8208                }
8209                ActivityInfo ainfo = mLastAddedTaskActivity;
8210                if (ainfo == null) {
8211                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8212                            comp, 0, UserHandle.getUserId(callingUid));
8213                    if (ainfo.applicationInfo.uid != callingUid) {
8214                        throw new SecurityException(
8215                                "Can't add task for another application: target uid="
8216                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8217                    }
8218                }
8219
8220                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8221                        intent, description);
8222
8223                int trimIdx = trimRecentsForTask(task, false);
8224                if (trimIdx >= 0) {
8225                    // If this would have caused a trim, then we'll abort because that
8226                    // means it would be added at the end of the list but then just removed.
8227                    return -1;
8228                }
8229
8230                final int N = mRecentTasks.size();
8231                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8232                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8233                    tr.removedFromRecents(mTaskPersister);
8234                }
8235
8236                task.inRecents = true;
8237                mRecentTasks.add(task);
8238                r.task.stack.addTask(task, false, false);
8239
8240                task.setLastThumbnail(thumbnail);
8241                task.freeLastThumbnail();
8242
8243                return task.taskId;
8244            }
8245        } finally {
8246            Binder.restoreCallingIdentity(callingIdent);
8247        }
8248    }
8249
8250    @Override
8251    public Point getAppTaskThumbnailSize() {
8252        synchronized (this) {
8253            return new Point(mThumbnailWidth,  mThumbnailHeight);
8254        }
8255    }
8256
8257    @Override
8258    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8259        synchronized (this) {
8260            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8261            if (r != null) {
8262                r.taskDescription = td;
8263                r.task.updateTaskDescription();
8264            }
8265        }
8266    }
8267
8268    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8269        mRecentTasks.remove(tr);
8270        tr.removedFromRecents(mTaskPersister);
8271        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8272        Intent baseIntent = new Intent(
8273                tr.intent != null ? tr.intent : tr.affinityIntent);
8274        ComponentName component = baseIntent.getComponent();
8275        if (component == null) {
8276            Slog.w(TAG, "Now component for base intent of task: " + tr);
8277            return;
8278        }
8279
8280        // Find any running services associated with this app.
8281        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8282
8283        if (killProcesses) {
8284            // Find any running processes associated with this app.
8285            final String pkg = component.getPackageName();
8286            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8287            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8288            for (int i=0; i<pmap.size(); i++) {
8289                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8290                for (int j=0; j<uids.size(); j++) {
8291                    ProcessRecord proc = uids.valueAt(j);
8292                    if (proc.userId != tr.userId) {
8293                        continue;
8294                    }
8295                    if (!proc.pkgList.containsKey(pkg)) {
8296                        continue;
8297                    }
8298                    procs.add(proc);
8299                }
8300            }
8301
8302            // Kill the running processes.
8303            for (int i=0; i<procs.size(); i++) {
8304                ProcessRecord pr = procs.get(i);
8305                if (pr == mHomeProcess) {
8306                    // Don't kill the home process along with tasks from the same package.
8307                    continue;
8308                }
8309                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8310                    pr.kill("remove task", true);
8311                } else {
8312                    pr.waitingToKill = "remove task";
8313                }
8314            }
8315        }
8316    }
8317
8318    /**
8319     * Removes the task with the specified task id.
8320     *
8321     * @param taskId Identifier of the task to be removed.
8322     * @param flags Additional operational flags.  May be 0 or
8323     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8324     * @return Returns true if the given task was found and removed.
8325     */
8326    private boolean removeTaskByIdLocked(int taskId, int flags) {
8327        TaskRecord tr = recentTaskForIdLocked(taskId);
8328        if (tr != null) {
8329            tr.removeTaskActivitiesLocked();
8330            cleanUpRemovedTaskLocked(tr, flags);
8331            if (tr.isPersistable) {
8332                notifyTaskPersisterLocked(null, true);
8333            }
8334            return true;
8335        }
8336        return false;
8337    }
8338
8339    @Override
8340    public boolean removeTask(int taskId, int flags) {
8341        synchronized (this) {
8342            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8343                    "removeTask()");
8344            long ident = Binder.clearCallingIdentity();
8345            try {
8346                return removeTaskByIdLocked(taskId, flags);
8347            } finally {
8348                Binder.restoreCallingIdentity(ident);
8349            }
8350        }
8351    }
8352
8353    /**
8354     * TODO: Add mController hook
8355     */
8356    @Override
8357    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8358        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8359                "moveTaskToFront()");
8360
8361        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8362        synchronized(this) {
8363            moveTaskToFrontLocked(taskId, flags, options);
8364        }
8365    }
8366
8367    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8368        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8369                Binder.getCallingUid(), "Task to front")) {
8370            ActivityOptions.abort(options);
8371            return;
8372        }
8373        final long origId = Binder.clearCallingIdentity();
8374        try {
8375            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8376            if (task == null) {
8377                return;
8378            }
8379            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8380                mStackSupervisor.showLockTaskToast();
8381                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8382                return;
8383            }
8384            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8385            if (prev != null && prev.isRecentsActivity()) {
8386                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8387            }
8388            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8389        } finally {
8390            Binder.restoreCallingIdentity(origId);
8391        }
8392        ActivityOptions.abort(options);
8393    }
8394
8395    @Override
8396    public void moveTaskToBack(int taskId) {
8397        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8398                "moveTaskToBack()");
8399
8400        synchronized(this) {
8401            TaskRecord tr = recentTaskForIdLocked(taskId);
8402            if (tr != null) {
8403                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8404                ActivityStack stack = tr.stack;
8405                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8406                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8407                            Binder.getCallingUid(), "Task to back")) {
8408                        return;
8409                    }
8410                }
8411                final long origId = Binder.clearCallingIdentity();
8412                try {
8413                    stack.moveTaskToBackLocked(taskId, null);
8414                } finally {
8415                    Binder.restoreCallingIdentity(origId);
8416                }
8417            }
8418        }
8419    }
8420
8421    /**
8422     * Moves an activity, and all of the other activities within the same task, to the bottom
8423     * of the history stack.  The activity's order within the task is unchanged.
8424     *
8425     * @param token A reference to the activity we wish to move
8426     * @param nonRoot If false then this only works if the activity is the root
8427     *                of a task; if true it will work for any activity in a task.
8428     * @return Returns true if the move completed, false if not.
8429     */
8430    @Override
8431    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8432        enforceNotIsolatedCaller("moveActivityTaskToBack");
8433        synchronized(this) {
8434            final long origId = Binder.clearCallingIdentity();
8435            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8436            if (taskId >= 0) {
8437                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8438            }
8439            Binder.restoreCallingIdentity(origId);
8440        }
8441        return false;
8442    }
8443
8444    @Override
8445    public void moveTaskBackwards(int task) {
8446        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8447                "moveTaskBackwards()");
8448
8449        synchronized(this) {
8450            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8451                    Binder.getCallingUid(), "Task backwards")) {
8452                return;
8453            }
8454            final long origId = Binder.clearCallingIdentity();
8455            moveTaskBackwardsLocked(task);
8456            Binder.restoreCallingIdentity(origId);
8457        }
8458    }
8459
8460    private final void moveTaskBackwardsLocked(int task) {
8461        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8462    }
8463
8464    @Override
8465    public IBinder getHomeActivityToken() throws RemoteException {
8466        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8467                "getHomeActivityToken()");
8468        synchronized (this) {
8469            return mStackSupervisor.getHomeActivityToken();
8470        }
8471    }
8472
8473    @Override
8474    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8475            IActivityContainerCallback callback) throws RemoteException {
8476        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8477                "createActivityContainer()");
8478        synchronized (this) {
8479            if (parentActivityToken == null) {
8480                throw new IllegalArgumentException("parent token must not be null");
8481            }
8482            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8483            if (r == null) {
8484                return null;
8485            }
8486            if (callback == null) {
8487                throw new IllegalArgumentException("callback must not be null");
8488            }
8489            return mStackSupervisor.createActivityContainer(r, callback);
8490        }
8491    }
8492
8493    @Override
8494    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8495        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8496                "deleteActivityContainer()");
8497        synchronized (this) {
8498            mStackSupervisor.deleteActivityContainer(container);
8499        }
8500    }
8501
8502    @Override
8503    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8504            throws RemoteException {
8505        synchronized (this) {
8506            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8507            if (stack != null) {
8508                return stack.mActivityContainer;
8509            }
8510            return null;
8511        }
8512    }
8513
8514    @Override
8515    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8516        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8517                "moveTaskToStack()");
8518        if (stackId == HOME_STACK_ID) {
8519            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8520                    new RuntimeException("here").fillInStackTrace());
8521        }
8522        synchronized (this) {
8523            long ident = Binder.clearCallingIdentity();
8524            try {
8525                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8526                        + stackId + " toTop=" + toTop);
8527                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8528            } finally {
8529                Binder.restoreCallingIdentity(ident);
8530            }
8531        }
8532    }
8533
8534    @Override
8535    public void resizeStack(int stackBoxId, Rect bounds) {
8536        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8537                "resizeStackBox()");
8538        long ident = Binder.clearCallingIdentity();
8539        try {
8540            mWindowManager.resizeStack(stackBoxId, bounds);
8541        } finally {
8542            Binder.restoreCallingIdentity(ident);
8543        }
8544    }
8545
8546    @Override
8547    public List<StackInfo> getAllStackInfos() {
8548        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8549                "getAllStackInfos()");
8550        long ident = Binder.clearCallingIdentity();
8551        try {
8552            synchronized (this) {
8553                return mStackSupervisor.getAllStackInfosLocked();
8554            }
8555        } finally {
8556            Binder.restoreCallingIdentity(ident);
8557        }
8558    }
8559
8560    @Override
8561    public StackInfo getStackInfo(int stackId) {
8562        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8563                "getStackInfo()");
8564        long ident = Binder.clearCallingIdentity();
8565        try {
8566            synchronized (this) {
8567                return mStackSupervisor.getStackInfoLocked(stackId);
8568            }
8569        } finally {
8570            Binder.restoreCallingIdentity(ident);
8571        }
8572    }
8573
8574    @Override
8575    public boolean isInHomeStack(int taskId) {
8576        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8577                "getStackInfo()");
8578        long ident = Binder.clearCallingIdentity();
8579        try {
8580            synchronized (this) {
8581                TaskRecord tr = recentTaskForIdLocked(taskId);
8582                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8583            }
8584        } finally {
8585            Binder.restoreCallingIdentity(ident);
8586        }
8587    }
8588
8589    @Override
8590    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8591        synchronized(this) {
8592            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8593        }
8594    }
8595
8596    private boolean isLockTaskAuthorized(String pkg) {
8597        final DevicePolicyManager dpm = (DevicePolicyManager)
8598                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8599        try {
8600            int uid = mContext.getPackageManager().getPackageUid(pkg,
8601                    Binder.getCallingUserHandle().getIdentifier());
8602            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8603        } catch (NameNotFoundException e) {
8604            return false;
8605        }
8606    }
8607
8608    void startLockTaskMode(TaskRecord task) {
8609        final String pkg;
8610        synchronized (this) {
8611            pkg = task.intent.getComponent().getPackageName();
8612        }
8613        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8614        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8615            final TaskRecord taskRecord = task;
8616            mHandler.post(new Runnable() {
8617                @Override
8618                public void run() {
8619                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8620                }
8621            });
8622            return;
8623        }
8624        long ident = Binder.clearCallingIdentity();
8625        try {
8626            synchronized (this) {
8627                // Since we lost lock on task, make sure it is still there.
8628                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8629                if (task != null) {
8630                    if (!isSystemInitiated
8631                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8632                        throw new IllegalArgumentException("Invalid task, not in foreground");
8633                    }
8634                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8635                }
8636            }
8637        } finally {
8638            Binder.restoreCallingIdentity(ident);
8639        }
8640    }
8641
8642    @Override
8643    public void startLockTaskMode(int taskId) {
8644        final TaskRecord task;
8645        long ident = Binder.clearCallingIdentity();
8646        try {
8647            synchronized (this) {
8648                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8649            }
8650        } finally {
8651            Binder.restoreCallingIdentity(ident);
8652        }
8653        if (task != null) {
8654            startLockTaskMode(task);
8655        }
8656    }
8657
8658    @Override
8659    public void startLockTaskMode(IBinder token) {
8660        final TaskRecord task;
8661        long ident = Binder.clearCallingIdentity();
8662        try {
8663            synchronized (this) {
8664                final ActivityRecord r = ActivityRecord.forToken(token);
8665                if (r == null) {
8666                    return;
8667                }
8668                task = r.task;
8669            }
8670        } finally {
8671            Binder.restoreCallingIdentity(ident);
8672        }
8673        if (task != null) {
8674            startLockTaskMode(task);
8675        }
8676    }
8677
8678    @Override
8679    public void startLockTaskModeOnCurrent() throws RemoteException {
8680        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8681        ActivityRecord r = null;
8682        synchronized (this) {
8683            r = mStackSupervisor.topRunningActivityLocked();
8684        }
8685        startLockTaskMode(r.task);
8686    }
8687
8688    @Override
8689    public void stopLockTaskMode() {
8690        // Verify that the user matches the package of the intent for the TaskRecord
8691        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8692        // and stopLockTaskMode.
8693        final int callingUid = Binder.getCallingUid();
8694        if (callingUid != Process.SYSTEM_UID) {
8695            try {
8696                String pkg =
8697                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8698                int uid = mContext.getPackageManager().getPackageUid(pkg,
8699                        Binder.getCallingUserHandle().getIdentifier());
8700                if (uid != callingUid) {
8701                    throw new SecurityException("Invalid uid, expected " + uid);
8702                }
8703            } catch (NameNotFoundException e) {
8704                Log.d(TAG, "stopLockTaskMode " + e);
8705                return;
8706            }
8707        }
8708        long ident = Binder.clearCallingIdentity();
8709        try {
8710            Log.d(TAG, "stopLockTaskMode");
8711            // Stop lock task
8712            synchronized (this) {
8713                mStackSupervisor.setLockTaskModeLocked(null, false);
8714            }
8715        } finally {
8716            Binder.restoreCallingIdentity(ident);
8717        }
8718    }
8719
8720    @Override
8721    public void stopLockTaskModeOnCurrent() throws RemoteException {
8722        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8723        long ident = Binder.clearCallingIdentity();
8724        try {
8725            stopLockTaskMode();
8726        } finally {
8727            Binder.restoreCallingIdentity(ident);
8728        }
8729    }
8730
8731    @Override
8732    public boolean isInLockTaskMode() {
8733        synchronized (this) {
8734            return mStackSupervisor.isInLockTaskMode();
8735        }
8736    }
8737
8738    // =========================================================
8739    // CONTENT PROVIDERS
8740    // =========================================================
8741
8742    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8743        List<ProviderInfo> providers = null;
8744        try {
8745            providers = AppGlobals.getPackageManager().
8746                queryContentProviders(app.processName, app.uid,
8747                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8748        } catch (RemoteException ex) {
8749        }
8750        if (DEBUG_MU)
8751            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8752        int userId = app.userId;
8753        if (providers != null) {
8754            int N = providers.size();
8755            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8756            for (int i=0; i<N; i++) {
8757                ProviderInfo cpi =
8758                    (ProviderInfo)providers.get(i);
8759                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8760                        cpi.name, cpi.flags);
8761                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8762                    // This is a singleton provider, but a user besides the
8763                    // default user is asking to initialize a process it runs
8764                    // in...  well, no, it doesn't actually run in this process,
8765                    // it runs in the process of the default user.  Get rid of it.
8766                    providers.remove(i);
8767                    N--;
8768                    i--;
8769                    continue;
8770                }
8771
8772                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8773                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8774                if (cpr == null) {
8775                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8776                    mProviderMap.putProviderByClass(comp, cpr);
8777                }
8778                if (DEBUG_MU)
8779                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8780                app.pubProviders.put(cpi.name, cpr);
8781                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8782                    // Don't add this if it is a platform component that is marked
8783                    // to run in multiple processes, because this is actually
8784                    // part of the framework so doesn't make sense to track as a
8785                    // separate apk in the process.
8786                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8787                            mProcessStats);
8788                }
8789                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8790            }
8791        }
8792        return providers;
8793    }
8794
8795    /**
8796     * Check if {@link ProcessRecord} has a possible chance at accessing the
8797     * given {@link ProviderInfo}. Final permission checking is always done
8798     * in {@link ContentProvider}.
8799     */
8800    private final String checkContentProviderPermissionLocked(
8801            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8802        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8803        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8804        boolean checkedGrants = false;
8805        if (checkUser) {
8806            // Looking for cross-user grants before enforcing the typical cross-users permissions
8807            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8808            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8809                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8810                    return null;
8811                }
8812                checkedGrants = true;
8813            }
8814            userId = handleIncomingUser(callingPid, callingUid, userId,
8815                    false, ALLOW_NON_FULL,
8816                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8817            if (userId != tmpTargetUserId) {
8818                // When we actually went to determine the final targer user ID, this ended
8819                // up different than our initial check for the authority.  This is because
8820                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8821                // SELF.  So we need to re-check the grants again.
8822                checkedGrants = false;
8823            }
8824        }
8825        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8826                cpi.applicationInfo.uid, cpi.exported)
8827                == PackageManager.PERMISSION_GRANTED) {
8828            return null;
8829        }
8830        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8831                cpi.applicationInfo.uid, cpi.exported)
8832                == PackageManager.PERMISSION_GRANTED) {
8833            return null;
8834        }
8835
8836        PathPermission[] pps = cpi.pathPermissions;
8837        if (pps != null) {
8838            int i = pps.length;
8839            while (i > 0) {
8840                i--;
8841                PathPermission pp = pps[i];
8842                String pprperm = pp.getReadPermission();
8843                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8844                        cpi.applicationInfo.uid, cpi.exported)
8845                        == PackageManager.PERMISSION_GRANTED) {
8846                    return null;
8847                }
8848                String ppwperm = pp.getWritePermission();
8849                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8850                        cpi.applicationInfo.uid, cpi.exported)
8851                        == PackageManager.PERMISSION_GRANTED) {
8852                    return null;
8853                }
8854            }
8855        }
8856        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8857            return null;
8858        }
8859
8860        String msg;
8861        if (!cpi.exported) {
8862            msg = "Permission Denial: opening provider " + cpi.name
8863                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8864                    + ", uid=" + callingUid + ") that is not exported from uid "
8865                    + cpi.applicationInfo.uid;
8866        } else {
8867            msg = "Permission Denial: opening provider " + cpi.name
8868                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8869                    + ", uid=" + callingUid + ") requires "
8870                    + cpi.readPermission + " or " + cpi.writePermission;
8871        }
8872        Slog.w(TAG, msg);
8873        return msg;
8874    }
8875
8876    /**
8877     * Returns if the ContentProvider has granted a uri to callingUid
8878     */
8879    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8880        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8881        if (perms != null) {
8882            for (int i=perms.size()-1; i>=0; i--) {
8883                GrantUri grantUri = perms.keyAt(i);
8884                if (grantUri.sourceUserId == userId || !checkUser) {
8885                    if (matchesProvider(grantUri.uri, cpi)) {
8886                        return true;
8887                    }
8888                }
8889            }
8890        }
8891        return false;
8892    }
8893
8894    /**
8895     * Returns true if the uri authority is one of the authorities specified in the provider.
8896     */
8897    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8898        String uriAuth = uri.getAuthority();
8899        String cpiAuth = cpi.authority;
8900        if (cpiAuth.indexOf(';') == -1) {
8901            return cpiAuth.equals(uriAuth);
8902        }
8903        String[] cpiAuths = cpiAuth.split(";");
8904        int length = cpiAuths.length;
8905        for (int i = 0; i < length; i++) {
8906            if (cpiAuths[i].equals(uriAuth)) return true;
8907        }
8908        return false;
8909    }
8910
8911    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8912            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8913        if (r != null) {
8914            for (int i=0; i<r.conProviders.size(); i++) {
8915                ContentProviderConnection conn = r.conProviders.get(i);
8916                if (conn.provider == cpr) {
8917                    if (DEBUG_PROVIDER) Slog.v(TAG,
8918                            "Adding provider requested by "
8919                            + r.processName + " from process "
8920                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8921                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8922                    if (stable) {
8923                        conn.stableCount++;
8924                        conn.numStableIncs++;
8925                    } else {
8926                        conn.unstableCount++;
8927                        conn.numUnstableIncs++;
8928                    }
8929                    return conn;
8930                }
8931            }
8932            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8933            if (stable) {
8934                conn.stableCount = 1;
8935                conn.numStableIncs = 1;
8936            } else {
8937                conn.unstableCount = 1;
8938                conn.numUnstableIncs = 1;
8939            }
8940            cpr.connections.add(conn);
8941            r.conProviders.add(conn);
8942            return conn;
8943        }
8944        cpr.addExternalProcessHandleLocked(externalProcessToken);
8945        return null;
8946    }
8947
8948    boolean decProviderCountLocked(ContentProviderConnection conn,
8949            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8950        if (conn != null) {
8951            cpr = conn.provider;
8952            if (DEBUG_PROVIDER) Slog.v(TAG,
8953                    "Removing provider requested by "
8954                    + conn.client.processName + " from process "
8955                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8956                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8957            if (stable) {
8958                conn.stableCount--;
8959            } else {
8960                conn.unstableCount--;
8961            }
8962            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8963                cpr.connections.remove(conn);
8964                conn.client.conProviders.remove(conn);
8965                return true;
8966            }
8967            return false;
8968        }
8969        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8970        return false;
8971    }
8972
8973    private void checkTime(long startTime, String where) {
8974        long now = SystemClock.elapsedRealtime();
8975        if ((now-startTime) > 1000) {
8976            // If we are taking more than a second, log about it.
8977            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8978        }
8979    }
8980
8981    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8982            String name, IBinder token, boolean stable, int userId) {
8983        ContentProviderRecord cpr;
8984        ContentProviderConnection conn = null;
8985        ProviderInfo cpi = null;
8986
8987        synchronized(this) {
8988            long startTime = SystemClock.elapsedRealtime();
8989
8990            ProcessRecord r = null;
8991            if (caller != null) {
8992                r = getRecordForAppLocked(caller);
8993                if (r == null) {
8994                    throw new SecurityException(
8995                            "Unable to find app for caller " + caller
8996                          + " (pid=" + Binder.getCallingPid()
8997                          + ") when getting content provider " + name);
8998                }
8999            }
9000
9001            boolean checkCrossUser = true;
9002
9003            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9004
9005            // First check if this content provider has been published...
9006            cpr = mProviderMap.getProviderByName(name, userId);
9007            // If that didn't work, check if it exists for user 0 and then
9008            // verify that it's a singleton provider before using it.
9009            if (cpr == null && userId != UserHandle.USER_OWNER) {
9010                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9011                if (cpr != null) {
9012                    cpi = cpr.info;
9013                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9014                            cpi.name, cpi.flags)
9015                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9016                        userId = UserHandle.USER_OWNER;
9017                        checkCrossUser = false;
9018                    } else {
9019                        cpr = null;
9020                        cpi = null;
9021                    }
9022                }
9023            }
9024
9025            boolean providerRunning = cpr != null;
9026            if (providerRunning) {
9027                cpi = cpr.info;
9028                String msg;
9029                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9030                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9031                        != null) {
9032                    throw new SecurityException(msg);
9033                }
9034                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9035
9036                if (r != null && cpr.canRunHere(r)) {
9037                    // This provider has been published or is in the process
9038                    // of being published...  but it is also allowed to run
9039                    // in the caller's process, so don't make a connection
9040                    // and just let the caller instantiate its own instance.
9041                    ContentProviderHolder holder = cpr.newHolder(null);
9042                    // don't give caller the provider object, it needs
9043                    // to make its own.
9044                    holder.provider = null;
9045                    return holder;
9046                }
9047
9048                final long origId = Binder.clearCallingIdentity();
9049
9050                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9051
9052                // In this case the provider instance already exists, so we can
9053                // return it right away.
9054                conn = incProviderCountLocked(r, cpr, token, stable);
9055                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9056                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9057                        // If this is a perceptible app accessing the provider,
9058                        // make sure to count it as being accessed and thus
9059                        // back up on the LRU list.  This is good because
9060                        // content providers are often expensive to start.
9061                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9062                        updateLruProcessLocked(cpr.proc, false, null);
9063                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9064                    }
9065                }
9066
9067                if (cpr.proc != null) {
9068                    if (false) {
9069                        if (cpr.name.flattenToShortString().equals(
9070                                "com.android.providers.calendar/.CalendarProvider2")) {
9071                            Slog.v(TAG, "****************** KILLING "
9072                                + cpr.name.flattenToShortString());
9073                            Process.killProcess(cpr.proc.pid);
9074                        }
9075                    }
9076                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9077                    boolean success = updateOomAdjLocked(cpr.proc);
9078                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9079                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9080                    // NOTE: there is still a race here where a signal could be
9081                    // pending on the process even though we managed to update its
9082                    // adj level.  Not sure what to do about this, but at least
9083                    // the race is now smaller.
9084                    if (!success) {
9085                        // Uh oh...  it looks like the provider's process
9086                        // has been killed on us.  We need to wait for a new
9087                        // process to be started, and make sure its death
9088                        // doesn't kill our process.
9089                        Slog.i(TAG,
9090                                "Existing provider " + cpr.name.flattenToShortString()
9091                                + " is crashing; detaching " + r);
9092                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9093                        checkTime(startTime, "getContentProviderImpl: before appDied");
9094                        appDiedLocked(cpr.proc);
9095                        checkTime(startTime, "getContentProviderImpl: after appDied");
9096                        if (!lastRef) {
9097                            // This wasn't the last ref our process had on
9098                            // the provider...  we have now been killed, bail.
9099                            return null;
9100                        }
9101                        providerRunning = false;
9102                        conn = null;
9103                    }
9104                }
9105
9106                Binder.restoreCallingIdentity(origId);
9107            }
9108
9109            boolean singleton;
9110            if (!providerRunning) {
9111                try {
9112                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9113                    cpi = AppGlobals.getPackageManager().
9114                        resolveContentProvider(name,
9115                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9116                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9117                } catch (RemoteException ex) {
9118                }
9119                if (cpi == null) {
9120                    return null;
9121                }
9122                // If the provider is a singleton AND
9123                // (it's a call within the same user || the provider is a
9124                // privileged app)
9125                // Then allow connecting to the singleton provider
9126                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9127                        cpi.name, cpi.flags)
9128                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9129                if (singleton) {
9130                    userId = UserHandle.USER_OWNER;
9131                }
9132                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9133                checkTime(startTime, "getContentProviderImpl: got app info for user");
9134
9135                String msg;
9136                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9137                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9138                        != null) {
9139                    throw new SecurityException(msg);
9140                }
9141                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9142
9143                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9144                        && !cpi.processName.equals("system")) {
9145                    // If this content provider does not run in the system
9146                    // process, and the system is not yet ready to run other
9147                    // processes, then fail fast instead of hanging.
9148                    throw new IllegalArgumentException(
9149                            "Attempt to launch content provider before system ready");
9150                }
9151
9152                // Make sure that the user who owns this provider is started.  If not,
9153                // we don't want to allow it to run.
9154                if (mStartedUsers.get(userId) == null) {
9155                    Slog.w(TAG, "Unable to launch app "
9156                            + cpi.applicationInfo.packageName + "/"
9157                            + cpi.applicationInfo.uid + " for provider "
9158                            + name + ": user " + userId + " is stopped");
9159                    return null;
9160                }
9161
9162                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9163                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9164                cpr = mProviderMap.getProviderByClass(comp, userId);
9165                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9166                final boolean firstClass = cpr == null;
9167                if (firstClass) {
9168                    try {
9169                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9170                        ApplicationInfo ai =
9171                            AppGlobals.getPackageManager().
9172                                getApplicationInfo(
9173                                        cpi.applicationInfo.packageName,
9174                                        STOCK_PM_FLAGS, userId);
9175                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9176                        if (ai == null) {
9177                            Slog.w(TAG, "No package info for content provider "
9178                                    + cpi.name);
9179                            return null;
9180                        }
9181                        ai = getAppInfoForUser(ai, userId);
9182                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9183                    } catch (RemoteException ex) {
9184                        // pm is in same process, this will never happen.
9185                    }
9186                }
9187
9188                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9189
9190                if (r != null && cpr.canRunHere(r)) {
9191                    // If this is a multiprocess provider, then just return its
9192                    // info and allow the caller to instantiate it.  Only do
9193                    // this if the provider is the same user as the caller's
9194                    // process, or can run as root (so can be in any process).
9195                    return cpr.newHolder(null);
9196                }
9197
9198                if (DEBUG_PROVIDER) {
9199                    RuntimeException e = new RuntimeException("here");
9200                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9201                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9202                }
9203
9204                // This is single process, and our app is now connecting to it.
9205                // See if we are already in the process of launching this
9206                // provider.
9207                final int N = mLaunchingProviders.size();
9208                int i;
9209                for (i=0; i<N; i++) {
9210                    if (mLaunchingProviders.get(i) == cpr) {
9211                        break;
9212                    }
9213                }
9214
9215                // If the provider is not already being launched, then get it
9216                // started.
9217                if (i >= N) {
9218                    final long origId = Binder.clearCallingIdentity();
9219
9220                    try {
9221                        // Content provider is now in use, its package can't be stopped.
9222                        try {
9223                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9224                            AppGlobals.getPackageManager().setPackageStoppedState(
9225                                    cpr.appInfo.packageName, false, userId);
9226                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9227                        } catch (RemoteException e) {
9228                        } catch (IllegalArgumentException e) {
9229                            Slog.w(TAG, "Failed trying to unstop package "
9230                                    + cpr.appInfo.packageName + ": " + e);
9231                        }
9232
9233                        // Use existing process if already started
9234                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9235                        ProcessRecord proc = getProcessRecordLocked(
9236                                cpi.processName, cpr.appInfo.uid, false);
9237                        if (proc != null && proc.thread != null) {
9238                            if (DEBUG_PROVIDER) {
9239                                Slog.d(TAG, "Installing in existing process " + proc);
9240                            }
9241                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9242                            proc.pubProviders.put(cpi.name, cpr);
9243                            try {
9244                                proc.thread.scheduleInstallProvider(cpi);
9245                            } catch (RemoteException e) {
9246                            }
9247                        } else {
9248                            checkTime(startTime, "getContentProviderImpl: before start process");
9249                            proc = startProcessLocked(cpi.processName,
9250                                    cpr.appInfo, false, 0, "content provider",
9251                                    new ComponentName(cpi.applicationInfo.packageName,
9252                                            cpi.name), false, false, false);
9253                            checkTime(startTime, "getContentProviderImpl: after start process");
9254                            if (proc == null) {
9255                                Slog.w(TAG, "Unable to launch app "
9256                                        + cpi.applicationInfo.packageName + "/"
9257                                        + cpi.applicationInfo.uid + " for provider "
9258                                        + name + ": process is bad");
9259                                return null;
9260                            }
9261                        }
9262                        cpr.launchingApp = proc;
9263                        mLaunchingProviders.add(cpr);
9264                    } finally {
9265                        Binder.restoreCallingIdentity(origId);
9266                    }
9267                }
9268
9269                checkTime(startTime, "getContentProviderImpl: updating data structures");
9270
9271                // Make sure the provider is published (the same provider class
9272                // may be published under multiple names).
9273                if (firstClass) {
9274                    mProviderMap.putProviderByClass(comp, cpr);
9275                }
9276
9277                mProviderMap.putProviderByName(name, cpr);
9278                conn = incProviderCountLocked(r, cpr, token, stable);
9279                if (conn != null) {
9280                    conn.waiting = true;
9281                }
9282            }
9283            checkTime(startTime, "getContentProviderImpl: done!");
9284        }
9285
9286        // Wait for the provider to be published...
9287        synchronized (cpr) {
9288            while (cpr.provider == null) {
9289                if (cpr.launchingApp == null) {
9290                    Slog.w(TAG, "Unable to launch app "
9291                            + cpi.applicationInfo.packageName + "/"
9292                            + cpi.applicationInfo.uid + " for provider "
9293                            + name + ": launching app became null");
9294                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9295                            UserHandle.getUserId(cpi.applicationInfo.uid),
9296                            cpi.applicationInfo.packageName,
9297                            cpi.applicationInfo.uid, name);
9298                    return null;
9299                }
9300                try {
9301                    if (DEBUG_MU) {
9302                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9303                                + cpr.launchingApp);
9304                    }
9305                    if (conn != null) {
9306                        conn.waiting = true;
9307                    }
9308                    cpr.wait();
9309                } catch (InterruptedException ex) {
9310                } finally {
9311                    if (conn != null) {
9312                        conn.waiting = false;
9313                    }
9314                }
9315            }
9316        }
9317        return cpr != null ? cpr.newHolder(conn) : null;
9318    }
9319
9320    @Override
9321    public final ContentProviderHolder getContentProvider(
9322            IApplicationThread caller, String name, int userId, boolean stable) {
9323        enforceNotIsolatedCaller("getContentProvider");
9324        if (caller == null) {
9325            String msg = "null IApplicationThread when getting content provider "
9326                    + name;
9327            Slog.w(TAG, msg);
9328            throw new SecurityException(msg);
9329        }
9330        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9331        // with cross-user grant.
9332        return getContentProviderImpl(caller, name, null, stable, userId);
9333    }
9334
9335    public ContentProviderHolder getContentProviderExternal(
9336            String name, int userId, IBinder token) {
9337        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9338            "Do not have permission in call getContentProviderExternal()");
9339        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9340                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9341        return getContentProviderExternalUnchecked(name, token, userId);
9342    }
9343
9344    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9345            IBinder token, int userId) {
9346        return getContentProviderImpl(null, name, token, true, userId);
9347    }
9348
9349    /**
9350     * Drop a content provider from a ProcessRecord's bookkeeping
9351     */
9352    public void removeContentProvider(IBinder connection, boolean stable) {
9353        enforceNotIsolatedCaller("removeContentProvider");
9354        long ident = Binder.clearCallingIdentity();
9355        try {
9356            synchronized (this) {
9357                ContentProviderConnection conn;
9358                try {
9359                    conn = (ContentProviderConnection)connection;
9360                } catch (ClassCastException e) {
9361                    String msg ="removeContentProvider: " + connection
9362                            + " not a ContentProviderConnection";
9363                    Slog.w(TAG, msg);
9364                    throw new IllegalArgumentException(msg);
9365                }
9366                if (conn == null) {
9367                    throw new NullPointerException("connection is null");
9368                }
9369                if (decProviderCountLocked(conn, null, null, stable)) {
9370                    updateOomAdjLocked();
9371                }
9372            }
9373        } finally {
9374            Binder.restoreCallingIdentity(ident);
9375        }
9376    }
9377
9378    public void removeContentProviderExternal(String name, IBinder token) {
9379        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9380            "Do not have permission in call removeContentProviderExternal()");
9381        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9382    }
9383
9384    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9385        synchronized (this) {
9386            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9387            if(cpr == null) {
9388                //remove from mProvidersByClass
9389                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9390                return;
9391            }
9392
9393            //update content provider record entry info
9394            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9395            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9396            if (localCpr.hasExternalProcessHandles()) {
9397                if (localCpr.removeExternalProcessHandleLocked(token)) {
9398                    updateOomAdjLocked();
9399                } else {
9400                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9401                            + " with no external reference for token: "
9402                            + token + ".");
9403                }
9404            } else {
9405                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9406                        + " with no external references.");
9407            }
9408        }
9409    }
9410
9411    public final void publishContentProviders(IApplicationThread caller,
9412            List<ContentProviderHolder> providers) {
9413        if (providers == null) {
9414            return;
9415        }
9416
9417        enforceNotIsolatedCaller("publishContentProviders");
9418        synchronized (this) {
9419            final ProcessRecord r = getRecordForAppLocked(caller);
9420            if (DEBUG_MU)
9421                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9422            if (r == null) {
9423                throw new SecurityException(
9424                        "Unable to find app for caller " + caller
9425                      + " (pid=" + Binder.getCallingPid()
9426                      + ") when publishing content providers");
9427            }
9428
9429            final long origId = Binder.clearCallingIdentity();
9430
9431            final int N = providers.size();
9432            for (int i=0; i<N; i++) {
9433                ContentProviderHolder src = providers.get(i);
9434                if (src == null || src.info == null || src.provider == null) {
9435                    continue;
9436                }
9437                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9438                if (DEBUG_MU)
9439                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9440                if (dst != null) {
9441                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9442                    mProviderMap.putProviderByClass(comp, dst);
9443                    String names[] = dst.info.authority.split(";");
9444                    for (int j = 0; j < names.length; j++) {
9445                        mProviderMap.putProviderByName(names[j], dst);
9446                    }
9447
9448                    int NL = mLaunchingProviders.size();
9449                    int j;
9450                    for (j=0; j<NL; j++) {
9451                        if (mLaunchingProviders.get(j) == dst) {
9452                            mLaunchingProviders.remove(j);
9453                            j--;
9454                            NL--;
9455                        }
9456                    }
9457                    synchronized (dst) {
9458                        dst.provider = src.provider;
9459                        dst.proc = r;
9460                        dst.notifyAll();
9461                    }
9462                    updateOomAdjLocked(r);
9463                }
9464            }
9465
9466            Binder.restoreCallingIdentity(origId);
9467        }
9468    }
9469
9470    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9471        ContentProviderConnection conn;
9472        try {
9473            conn = (ContentProviderConnection)connection;
9474        } catch (ClassCastException e) {
9475            String msg ="refContentProvider: " + connection
9476                    + " not a ContentProviderConnection";
9477            Slog.w(TAG, msg);
9478            throw new IllegalArgumentException(msg);
9479        }
9480        if (conn == null) {
9481            throw new NullPointerException("connection is null");
9482        }
9483
9484        synchronized (this) {
9485            if (stable > 0) {
9486                conn.numStableIncs += stable;
9487            }
9488            stable = conn.stableCount + stable;
9489            if (stable < 0) {
9490                throw new IllegalStateException("stableCount < 0: " + stable);
9491            }
9492
9493            if (unstable > 0) {
9494                conn.numUnstableIncs += unstable;
9495            }
9496            unstable = conn.unstableCount + unstable;
9497            if (unstable < 0) {
9498                throw new IllegalStateException("unstableCount < 0: " + unstable);
9499            }
9500
9501            if ((stable+unstable) <= 0) {
9502                throw new IllegalStateException("ref counts can't go to zero here: stable="
9503                        + stable + " unstable=" + unstable);
9504            }
9505            conn.stableCount = stable;
9506            conn.unstableCount = unstable;
9507            return !conn.dead;
9508        }
9509    }
9510
9511    public void unstableProviderDied(IBinder connection) {
9512        ContentProviderConnection conn;
9513        try {
9514            conn = (ContentProviderConnection)connection;
9515        } catch (ClassCastException e) {
9516            String msg ="refContentProvider: " + connection
9517                    + " not a ContentProviderConnection";
9518            Slog.w(TAG, msg);
9519            throw new IllegalArgumentException(msg);
9520        }
9521        if (conn == null) {
9522            throw new NullPointerException("connection is null");
9523        }
9524
9525        // Safely retrieve the content provider associated with the connection.
9526        IContentProvider provider;
9527        synchronized (this) {
9528            provider = conn.provider.provider;
9529        }
9530
9531        if (provider == null) {
9532            // Um, yeah, we're way ahead of you.
9533            return;
9534        }
9535
9536        // Make sure the caller is being honest with us.
9537        if (provider.asBinder().pingBinder()) {
9538            // Er, no, still looks good to us.
9539            synchronized (this) {
9540                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9541                        + " says " + conn + " died, but we don't agree");
9542                return;
9543            }
9544        }
9545
9546        // Well look at that!  It's dead!
9547        synchronized (this) {
9548            if (conn.provider.provider != provider) {
9549                // But something changed...  good enough.
9550                return;
9551            }
9552
9553            ProcessRecord proc = conn.provider.proc;
9554            if (proc == null || proc.thread == null) {
9555                // Seems like the process is already cleaned up.
9556                return;
9557            }
9558
9559            // As far as we're concerned, this is just like receiving a
9560            // death notification...  just a bit prematurely.
9561            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9562                    + ") early provider death");
9563            final long ident = Binder.clearCallingIdentity();
9564            try {
9565                appDiedLocked(proc);
9566            } finally {
9567                Binder.restoreCallingIdentity(ident);
9568            }
9569        }
9570    }
9571
9572    @Override
9573    public void appNotRespondingViaProvider(IBinder connection) {
9574        enforceCallingPermission(
9575                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9576
9577        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9578        if (conn == null) {
9579            Slog.w(TAG, "ContentProviderConnection is null");
9580            return;
9581        }
9582
9583        final ProcessRecord host = conn.provider.proc;
9584        if (host == null) {
9585            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9586            return;
9587        }
9588
9589        final long token = Binder.clearCallingIdentity();
9590        try {
9591            appNotResponding(host, null, null, false, "ContentProvider not responding");
9592        } finally {
9593            Binder.restoreCallingIdentity(token);
9594        }
9595    }
9596
9597    public final void installSystemProviders() {
9598        List<ProviderInfo> providers;
9599        synchronized (this) {
9600            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9601            providers = generateApplicationProvidersLocked(app);
9602            if (providers != null) {
9603                for (int i=providers.size()-1; i>=0; i--) {
9604                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9605                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9606                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9607                                + ": not system .apk");
9608                        providers.remove(i);
9609                    }
9610                }
9611            }
9612        }
9613        if (providers != null) {
9614            mSystemThread.installSystemProviders(providers);
9615        }
9616
9617        mCoreSettingsObserver = new CoreSettingsObserver(this);
9618
9619        //mUsageStatsService.monitorPackages();
9620    }
9621
9622    /**
9623     * Allows apps to retrieve the MIME type of a URI.
9624     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9625     * users, then it does not need permission to access the ContentProvider.
9626     * Either, it needs cross-user uri grants.
9627     *
9628     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9629     *
9630     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9631     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9632     */
9633    public String getProviderMimeType(Uri uri, int userId) {
9634        enforceNotIsolatedCaller("getProviderMimeType");
9635        final String name = uri.getAuthority();
9636        int callingUid = Binder.getCallingUid();
9637        int callingPid = Binder.getCallingPid();
9638        long ident = 0;
9639        boolean clearedIdentity = false;
9640        userId = unsafeConvertIncomingUser(userId);
9641        if (UserHandle.getUserId(callingUid) != userId) {
9642            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9643                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9644                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9645                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9646                clearedIdentity = true;
9647                ident = Binder.clearCallingIdentity();
9648            }
9649        }
9650        ContentProviderHolder holder = null;
9651        try {
9652            holder = getContentProviderExternalUnchecked(name, null, userId);
9653            if (holder != null) {
9654                return holder.provider.getType(uri);
9655            }
9656        } catch (RemoteException e) {
9657            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9658            return null;
9659        } finally {
9660            // We need to clear the identity to call removeContentProviderExternalUnchecked
9661            if (!clearedIdentity) {
9662                ident = Binder.clearCallingIdentity();
9663            }
9664            try {
9665                if (holder != null) {
9666                    removeContentProviderExternalUnchecked(name, null, userId);
9667                }
9668            } finally {
9669                Binder.restoreCallingIdentity(ident);
9670            }
9671        }
9672
9673        return null;
9674    }
9675
9676    // =========================================================
9677    // GLOBAL MANAGEMENT
9678    // =========================================================
9679
9680    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9681            boolean isolated, int isolatedUid) {
9682        String proc = customProcess != null ? customProcess : info.processName;
9683        BatteryStatsImpl.Uid.Proc ps = null;
9684        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9685        int uid = info.uid;
9686        if (isolated) {
9687            if (isolatedUid == 0) {
9688                int userId = UserHandle.getUserId(uid);
9689                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9690                while (true) {
9691                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9692                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9693                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9694                    }
9695                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9696                    mNextIsolatedProcessUid++;
9697                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9698                        // No process for this uid, use it.
9699                        break;
9700                    }
9701                    stepsLeft--;
9702                    if (stepsLeft <= 0) {
9703                        return null;
9704                    }
9705                }
9706            } else {
9707                // Special case for startIsolatedProcess (internal only), where
9708                // the uid of the isolated process is specified by the caller.
9709                uid = isolatedUid;
9710            }
9711        }
9712        return new ProcessRecord(stats, info, proc, uid);
9713    }
9714
9715    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9716            String abiOverride) {
9717        ProcessRecord app;
9718        if (!isolated) {
9719            app = getProcessRecordLocked(info.processName, info.uid, true);
9720        } else {
9721            app = null;
9722        }
9723
9724        if (app == null) {
9725            app = newProcessRecordLocked(info, null, isolated, 0);
9726            mProcessNames.put(info.processName, app.uid, app);
9727            if (isolated) {
9728                mIsolatedProcesses.put(app.uid, app);
9729            }
9730            updateLruProcessLocked(app, false, null);
9731            updateOomAdjLocked();
9732        }
9733
9734        // This package really, really can not be stopped.
9735        try {
9736            AppGlobals.getPackageManager().setPackageStoppedState(
9737                    info.packageName, false, UserHandle.getUserId(app.uid));
9738        } catch (RemoteException e) {
9739        } catch (IllegalArgumentException e) {
9740            Slog.w(TAG, "Failed trying to unstop package "
9741                    + info.packageName + ": " + e);
9742        }
9743
9744        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9745                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9746            app.persistent = true;
9747            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9748        }
9749        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9750            mPersistentStartingProcesses.add(app);
9751            startProcessLocked(app, "added application", app.processName, abiOverride,
9752                    null /* entryPoint */, null /* entryPointArgs */);
9753        }
9754
9755        return app;
9756    }
9757
9758    public void unhandledBack() {
9759        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9760                "unhandledBack()");
9761
9762        synchronized(this) {
9763            final long origId = Binder.clearCallingIdentity();
9764            try {
9765                getFocusedStack().unhandledBackLocked();
9766            } finally {
9767                Binder.restoreCallingIdentity(origId);
9768            }
9769        }
9770    }
9771
9772    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9773        enforceNotIsolatedCaller("openContentUri");
9774        final int userId = UserHandle.getCallingUserId();
9775        String name = uri.getAuthority();
9776        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9777        ParcelFileDescriptor pfd = null;
9778        if (cph != null) {
9779            // We record the binder invoker's uid in thread-local storage before
9780            // going to the content provider to open the file.  Later, in the code
9781            // that handles all permissions checks, we look for this uid and use
9782            // that rather than the Activity Manager's own uid.  The effect is that
9783            // we do the check against the caller's permissions even though it looks
9784            // to the content provider like the Activity Manager itself is making
9785            // the request.
9786            sCallerIdentity.set(new Identity(
9787                    Binder.getCallingPid(), Binder.getCallingUid()));
9788            try {
9789                pfd = cph.provider.openFile(null, uri, "r", null);
9790            } catch (FileNotFoundException e) {
9791                // do nothing; pfd will be returned null
9792            } finally {
9793                // Ensure that whatever happens, we clean up the identity state
9794                sCallerIdentity.remove();
9795            }
9796
9797            // We've got the fd now, so we're done with the provider.
9798            removeContentProviderExternalUnchecked(name, null, userId);
9799        } else {
9800            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9801        }
9802        return pfd;
9803    }
9804
9805    // Actually is sleeping or shutting down or whatever else in the future
9806    // is an inactive state.
9807    public boolean isSleepingOrShuttingDown() {
9808        return mSleeping || mShuttingDown;
9809    }
9810
9811    public boolean isSleeping() {
9812        return mSleeping;
9813    }
9814
9815    void goingToSleep() {
9816        synchronized(this) {
9817            mWentToSleep = true;
9818            updateEventDispatchingLocked();
9819            goToSleepIfNeededLocked();
9820        }
9821    }
9822
9823    void finishRunningVoiceLocked() {
9824        if (mRunningVoice) {
9825            mRunningVoice = false;
9826            goToSleepIfNeededLocked();
9827        }
9828    }
9829
9830    void goToSleepIfNeededLocked() {
9831        if (mWentToSleep && !mRunningVoice) {
9832            if (!mSleeping) {
9833                mSleeping = true;
9834                mStackSupervisor.goingToSleepLocked();
9835
9836                // Initialize the wake times of all processes.
9837                checkExcessivePowerUsageLocked(false);
9838                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9839                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9840                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9841            }
9842        }
9843    }
9844
9845    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9846        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9847            // Never persist the home stack.
9848            return;
9849        }
9850        mTaskPersister.wakeup(task, flush);
9851    }
9852
9853    @Override
9854    public boolean shutdown(int timeout) {
9855        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9856                != PackageManager.PERMISSION_GRANTED) {
9857            throw new SecurityException("Requires permission "
9858                    + android.Manifest.permission.SHUTDOWN);
9859        }
9860
9861        boolean timedout = false;
9862
9863        synchronized(this) {
9864            mShuttingDown = true;
9865            updateEventDispatchingLocked();
9866            timedout = mStackSupervisor.shutdownLocked(timeout);
9867        }
9868
9869        mAppOpsService.shutdown();
9870        if (mUsageStatsService != null) {
9871            mUsageStatsService.prepareShutdown();
9872        }
9873        mBatteryStatsService.shutdown();
9874        synchronized (this) {
9875            mProcessStats.shutdownLocked();
9876        }
9877        notifyTaskPersisterLocked(null, true);
9878
9879        return timedout;
9880    }
9881
9882    public final void activitySlept(IBinder token) {
9883        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9884
9885        final long origId = Binder.clearCallingIdentity();
9886
9887        synchronized (this) {
9888            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9889            if (r != null) {
9890                mStackSupervisor.activitySleptLocked(r);
9891            }
9892        }
9893
9894        Binder.restoreCallingIdentity(origId);
9895    }
9896
9897    void logLockScreen(String msg) {
9898        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9899                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9900                mWentToSleep + " mSleeping=" + mSleeping);
9901    }
9902
9903    private void comeOutOfSleepIfNeededLocked() {
9904        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9905            if (mSleeping) {
9906                mSleeping = false;
9907                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9908            }
9909        }
9910    }
9911
9912    void wakingUp() {
9913        synchronized(this) {
9914            mWentToSleep = false;
9915            updateEventDispatchingLocked();
9916            comeOutOfSleepIfNeededLocked();
9917        }
9918    }
9919
9920    void startRunningVoiceLocked() {
9921        if (!mRunningVoice) {
9922            mRunningVoice = true;
9923            comeOutOfSleepIfNeededLocked();
9924        }
9925    }
9926
9927    private void updateEventDispatchingLocked() {
9928        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9929    }
9930
9931    public void setLockScreenShown(boolean shown) {
9932        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9933                != PackageManager.PERMISSION_GRANTED) {
9934            throw new SecurityException("Requires permission "
9935                    + android.Manifest.permission.DEVICE_POWER);
9936        }
9937
9938        synchronized(this) {
9939            long ident = Binder.clearCallingIdentity();
9940            try {
9941                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9942                mLockScreenShown = shown;
9943                comeOutOfSleepIfNeededLocked();
9944            } finally {
9945                Binder.restoreCallingIdentity(ident);
9946            }
9947        }
9948    }
9949
9950    @Override
9951    public void stopAppSwitches() {
9952        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9953                != PackageManager.PERMISSION_GRANTED) {
9954            throw new SecurityException("Requires permission "
9955                    + android.Manifest.permission.STOP_APP_SWITCHES);
9956        }
9957
9958        synchronized(this) {
9959            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9960                    + APP_SWITCH_DELAY_TIME;
9961            mDidAppSwitch = false;
9962            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9963            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9964            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9965        }
9966    }
9967
9968    public void resumeAppSwitches() {
9969        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9970                != PackageManager.PERMISSION_GRANTED) {
9971            throw new SecurityException("Requires permission "
9972                    + android.Manifest.permission.STOP_APP_SWITCHES);
9973        }
9974
9975        synchronized(this) {
9976            // Note that we don't execute any pending app switches... we will
9977            // let those wait until either the timeout, or the next start
9978            // activity request.
9979            mAppSwitchesAllowedTime = 0;
9980        }
9981    }
9982
9983    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9984            String name) {
9985        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9986            return true;
9987        }
9988
9989        final int perm = checkComponentPermission(
9990                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9991                callingUid, -1, true);
9992        if (perm == PackageManager.PERMISSION_GRANTED) {
9993            return true;
9994        }
9995
9996        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9997        return false;
9998    }
9999
10000    public void setDebugApp(String packageName, boolean waitForDebugger,
10001            boolean persistent) {
10002        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10003                "setDebugApp()");
10004
10005        long ident = Binder.clearCallingIdentity();
10006        try {
10007            // Note that this is not really thread safe if there are multiple
10008            // callers into it at the same time, but that's not a situation we
10009            // care about.
10010            if (persistent) {
10011                final ContentResolver resolver = mContext.getContentResolver();
10012                Settings.Global.putString(
10013                    resolver, Settings.Global.DEBUG_APP,
10014                    packageName);
10015                Settings.Global.putInt(
10016                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10017                    waitForDebugger ? 1 : 0);
10018            }
10019
10020            synchronized (this) {
10021                if (!persistent) {
10022                    mOrigDebugApp = mDebugApp;
10023                    mOrigWaitForDebugger = mWaitForDebugger;
10024                }
10025                mDebugApp = packageName;
10026                mWaitForDebugger = waitForDebugger;
10027                mDebugTransient = !persistent;
10028                if (packageName != null) {
10029                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10030                            false, UserHandle.USER_ALL, "set debug app");
10031                }
10032            }
10033        } finally {
10034            Binder.restoreCallingIdentity(ident);
10035        }
10036    }
10037
10038    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10039        synchronized (this) {
10040            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10041            if (!isDebuggable) {
10042                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10043                    throw new SecurityException("Process not debuggable: " + app.packageName);
10044                }
10045            }
10046
10047            mOpenGlTraceApp = processName;
10048        }
10049    }
10050
10051    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10052        synchronized (this) {
10053            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10054            if (!isDebuggable) {
10055                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10056                    throw new SecurityException("Process not debuggable: " + app.packageName);
10057                }
10058            }
10059            mProfileApp = processName;
10060            mProfileFile = profilerInfo.profileFile;
10061            if (mProfileFd != null) {
10062                try {
10063                    mProfileFd.close();
10064                } catch (IOException e) {
10065                }
10066                mProfileFd = null;
10067            }
10068            mProfileFd = profilerInfo.profileFd;
10069            mSamplingInterval = profilerInfo.samplingInterval;
10070            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10071            mProfileType = 0;
10072        }
10073    }
10074
10075    @Override
10076    public void setAlwaysFinish(boolean enabled) {
10077        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10078                "setAlwaysFinish()");
10079
10080        Settings.Global.putInt(
10081                mContext.getContentResolver(),
10082                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10083
10084        synchronized (this) {
10085            mAlwaysFinishActivities = enabled;
10086        }
10087    }
10088
10089    @Override
10090    public void setActivityController(IActivityController controller) {
10091        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10092                "setActivityController()");
10093        synchronized (this) {
10094            mController = controller;
10095            Watchdog.getInstance().setActivityController(controller);
10096        }
10097    }
10098
10099    @Override
10100    public void setUserIsMonkey(boolean userIsMonkey) {
10101        synchronized (this) {
10102            synchronized (mPidsSelfLocked) {
10103                final int callingPid = Binder.getCallingPid();
10104                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10105                if (precessRecord == null) {
10106                    throw new SecurityException("Unknown process: " + callingPid);
10107                }
10108                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10109                    throw new SecurityException("Only an instrumentation process "
10110                            + "with a UiAutomation can call setUserIsMonkey");
10111                }
10112            }
10113            mUserIsMonkey = userIsMonkey;
10114        }
10115    }
10116
10117    @Override
10118    public boolean isUserAMonkey() {
10119        synchronized (this) {
10120            // If there is a controller also implies the user is a monkey.
10121            return (mUserIsMonkey || mController != null);
10122        }
10123    }
10124
10125    public void requestBugReport() {
10126        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10127        SystemProperties.set("ctl.start", "bugreport");
10128    }
10129
10130    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10131        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10132    }
10133
10134    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10135        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10136            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10137        }
10138        return KEY_DISPATCHING_TIMEOUT;
10139    }
10140
10141    @Override
10142    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10143        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10144                != PackageManager.PERMISSION_GRANTED) {
10145            throw new SecurityException("Requires permission "
10146                    + android.Manifest.permission.FILTER_EVENTS);
10147        }
10148        ProcessRecord proc;
10149        long timeout;
10150        synchronized (this) {
10151            synchronized (mPidsSelfLocked) {
10152                proc = mPidsSelfLocked.get(pid);
10153            }
10154            timeout = getInputDispatchingTimeoutLocked(proc);
10155        }
10156
10157        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10158            return -1;
10159        }
10160
10161        return timeout;
10162    }
10163
10164    /**
10165     * Handle input dispatching timeouts.
10166     * Returns whether input dispatching should be aborted or not.
10167     */
10168    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10169            final ActivityRecord activity, final ActivityRecord parent,
10170            final boolean aboveSystem, String reason) {
10171        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10172                != PackageManager.PERMISSION_GRANTED) {
10173            throw new SecurityException("Requires permission "
10174                    + android.Manifest.permission.FILTER_EVENTS);
10175        }
10176
10177        final String annotation;
10178        if (reason == null) {
10179            annotation = "Input dispatching timed out";
10180        } else {
10181            annotation = "Input dispatching timed out (" + reason + ")";
10182        }
10183
10184        if (proc != null) {
10185            synchronized (this) {
10186                if (proc.debugging) {
10187                    return false;
10188                }
10189
10190                if (mDidDexOpt) {
10191                    // Give more time since we were dexopting.
10192                    mDidDexOpt = false;
10193                    return false;
10194                }
10195
10196                if (proc.instrumentationClass != null) {
10197                    Bundle info = new Bundle();
10198                    info.putString("shortMsg", "keyDispatchingTimedOut");
10199                    info.putString("longMsg", annotation);
10200                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10201                    return true;
10202                }
10203            }
10204            mHandler.post(new Runnable() {
10205                @Override
10206                public void run() {
10207                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10208                }
10209            });
10210        }
10211
10212        return true;
10213    }
10214
10215    public Bundle getAssistContextExtras(int requestType) {
10216        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10217                "getAssistContextExtras()");
10218        PendingAssistExtras pae;
10219        Bundle extras = new Bundle();
10220        synchronized (this) {
10221            ActivityRecord activity = getFocusedStack().mResumedActivity;
10222            if (activity == null) {
10223                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10224                return null;
10225            }
10226            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10227            if (activity.app == null || activity.app.thread == null) {
10228                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10229                return extras;
10230            }
10231            if (activity.app.pid == Binder.getCallingPid()) {
10232                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10233                return extras;
10234            }
10235            pae = new PendingAssistExtras(activity);
10236            try {
10237                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10238                        requestType);
10239                mPendingAssistExtras.add(pae);
10240                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10241            } catch (RemoteException e) {
10242                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10243                return extras;
10244            }
10245        }
10246        synchronized (pae) {
10247            while (!pae.haveResult) {
10248                try {
10249                    pae.wait();
10250                } catch (InterruptedException e) {
10251                }
10252            }
10253            if (pae.result != null) {
10254                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10255            }
10256        }
10257        synchronized (this) {
10258            mPendingAssistExtras.remove(pae);
10259            mHandler.removeCallbacks(pae);
10260        }
10261        return extras;
10262    }
10263
10264    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10265        PendingAssistExtras pae = (PendingAssistExtras)token;
10266        synchronized (pae) {
10267            pae.result = extras;
10268            pae.haveResult = true;
10269            pae.notifyAll();
10270        }
10271    }
10272
10273    public void registerProcessObserver(IProcessObserver observer) {
10274        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10275                "registerProcessObserver()");
10276        synchronized (this) {
10277            mProcessObservers.register(observer);
10278        }
10279    }
10280
10281    @Override
10282    public void unregisterProcessObserver(IProcessObserver observer) {
10283        synchronized (this) {
10284            mProcessObservers.unregister(observer);
10285        }
10286    }
10287
10288    @Override
10289    public boolean convertFromTranslucent(IBinder token) {
10290        final long origId = Binder.clearCallingIdentity();
10291        try {
10292            synchronized (this) {
10293                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10294                if (r == null) {
10295                    return false;
10296                }
10297                if (r.changeWindowTranslucency(true)) {
10298                    mWindowManager.setAppFullscreen(token, true);
10299                    r.task.stack.releaseBackgroundResources();
10300                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10301                    return true;
10302                }
10303                return false;
10304            }
10305        } finally {
10306            Binder.restoreCallingIdentity(origId);
10307        }
10308    }
10309
10310    @Override
10311    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10312        final long origId = Binder.clearCallingIdentity();
10313        try {
10314            synchronized (this) {
10315                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10316                if (r == null) {
10317                    return false;
10318                }
10319                int index = r.task.mActivities.lastIndexOf(r);
10320                if (index > 0) {
10321                    ActivityRecord under = r.task.mActivities.get(index - 1);
10322                    under.returningOptions = options;
10323                }
10324                if (r.changeWindowTranslucency(false)) {
10325                    r.task.stack.convertToTranslucent(r);
10326                    mWindowManager.setAppFullscreen(token, false);
10327                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10328                    return true;
10329                } else {
10330                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10331                    return false;
10332                }
10333            }
10334        } finally {
10335            Binder.restoreCallingIdentity(origId);
10336        }
10337    }
10338
10339    @Override
10340    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10341        final long origId = Binder.clearCallingIdentity();
10342        try {
10343            synchronized (this) {
10344                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10345                if (r != null) {
10346                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10347                }
10348            }
10349            return false;
10350        } finally {
10351            Binder.restoreCallingIdentity(origId);
10352        }
10353    }
10354
10355    @Override
10356    public boolean isBackgroundVisibleBehind(IBinder token) {
10357        final long origId = Binder.clearCallingIdentity();
10358        try {
10359            synchronized (this) {
10360                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10361                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10362                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10363                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10364                return visible;
10365            }
10366        } finally {
10367            Binder.restoreCallingIdentity(origId);
10368        }
10369    }
10370
10371    @Override
10372    public ActivityOptions getActivityOptions(IBinder token) {
10373        final long origId = Binder.clearCallingIdentity();
10374        try {
10375            synchronized (this) {
10376                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10377                if (r != null) {
10378                    final ActivityOptions activityOptions = r.pendingOptions;
10379                    r.pendingOptions = null;
10380                    return activityOptions;
10381                }
10382                return null;
10383            }
10384        } finally {
10385            Binder.restoreCallingIdentity(origId);
10386        }
10387    }
10388
10389    @Override
10390    public void setImmersive(IBinder token, boolean immersive) {
10391        synchronized(this) {
10392            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10393            if (r == null) {
10394                throw new IllegalArgumentException();
10395            }
10396            r.immersive = immersive;
10397
10398            // update associated state if we're frontmost
10399            if (r == mFocusedActivity) {
10400                if (DEBUG_IMMERSIVE) {
10401                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10402                }
10403                applyUpdateLockStateLocked(r);
10404            }
10405        }
10406    }
10407
10408    @Override
10409    public boolean isImmersive(IBinder token) {
10410        synchronized (this) {
10411            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10412            if (r == null) {
10413                throw new IllegalArgumentException();
10414            }
10415            return r.immersive;
10416        }
10417    }
10418
10419    public boolean isTopActivityImmersive() {
10420        enforceNotIsolatedCaller("startActivity");
10421        synchronized (this) {
10422            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10423            return (r != null) ? r.immersive : false;
10424        }
10425    }
10426
10427    @Override
10428    public boolean isTopOfTask(IBinder token) {
10429        synchronized (this) {
10430            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10431            if (r == null) {
10432                throw new IllegalArgumentException();
10433            }
10434            return r.task.getTopActivity() == r;
10435        }
10436    }
10437
10438    public final void enterSafeMode() {
10439        synchronized(this) {
10440            // It only makes sense to do this before the system is ready
10441            // and started launching other packages.
10442            if (!mSystemReady) {
10443                try {
10444                    AppGlobals.getPackageManager().enterSafeMode();
10445                } catch (RemoteException e) {
10446                }
10447            }
10448
10449            mSafeMode = true;
10450        }
10451    }
10452
10453    public final void showSafeModeOverlay() {
10454        View v = LayoutInflater.from(mContext).inflate(
10455                com.android.internal.R.layout.safe_mode, null);
10456        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10457        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10458        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10459        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10460        lp.gravity = Gravity.BOTTOM | Gravity.START;
10461        lp.format = v.getBackground().getOpacity();
10462        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10463                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10464        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10465        ((WindowManager)mContext.getSystemService(
10466                Context.WINDOW_SERVICE)).addView(v, lp);
10467    }
10468
10469    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10470        if (!(sender instanceof PendingIntentRecord)) {
10471            return;
10472        }
10473        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10474        synchronized (stats) {
10475            if (mBatteryStatsService.isOnBattery()) {
10476                mBatteryStatsService.enforceCallingPermission();
10477                PendingIntentRecord rec = (PendingIntentRecord)sender;
10478                int MY_UID = Binder.getCallingUid();
10479                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10480                BatteryStatsImpl.Uid.Pkg pkg =
10481                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10482                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10483                pkg.incWakeupsLocked();
10484            }
10485        }
10486    }
10487
10488    public boolean killPids(int[] pids, String pReason, boolean secure) {
10489        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10490            throw new SecurityException("killPids only available to the system");
10491        }
10492        String reason = (pReason == null) ? "Unknown" : pReason;
10493        // XXX Note: don't acquire main activity lock here, because the window
10494        // manager calls in with its locks held.
10495
10496        boolean killed = false;
10497        synchronized (mPidsSelfLocked) {
10498            int[] types = new int[pids.length];
10499            int worstType = 0;
10500            for (int i=0; i<pids.length; i++) {
10501                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10502                if (proc != null) {
10503                    int type = proc.setAdj;
10504                    types[i] = type;
10505                    if (type > worstType) {
10506                        worstType = type;
10507                    }
10508                }
10509            }
10510
10511            // If the worst oom_adj is somewhere in the cached proc LRU range,
10512            // then constrain it so we will kill all cached procs.
10513            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10514                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10515                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10516            }
10517
10518            // If this is not a secure call, don't let it kill processes that
10519            // are important.
10520            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10521                worstType = ProcessList.SERVICE_ADJ;
10522            }
10523
10524            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10525            for (int i=0; i<pids.length; i++) {
10526                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10527                if (proc == null) {
10528                    continue;
10529                }
10530                int adj = proc.setAdj;
10531                if (adj >= worstType && !proc.killedByAm) {
10532                    proc.kill(reason, true);
10533                    killed = true;
10534                }
10535            }
10536        }
10537        return killed;
10538    }
10539
10540    @Override
10541    public void killUid(int uid, String reason) {
10542        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10543            throw new SecurityException("killUid only available to the system");
10544        }
10545        synchronized (this) {
10546            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10547                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10548                    reason != null ? reason : "kill uid");
10549        }
10550    }
10551
10552    @Override
10553    public boolean killProcessesBelowForeground(String reason) {
10554        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10555            throw new SecurityException("killProcessesBelowForeground() only available to system");
10556        }
10557
10558        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10559    }
10560
10561    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10562        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10563            throw new SecurityException("killProcessesBelowAdj() only available to system");
10564        }
10565
10566        boolean killed = false;
10567        synchronized (mPidsSelfLocked) {
10568            final int size = mPidsSelfLocked.size();
10569            for (int i = 0; i < size; i++) {
10570                final int pid = mPidsSelfLocked.keyAt(i);
10571                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10572                if (proc == null) continue;
10573
10574                final int adj = proc.setAdj;
10575                if (adj > belowAdj && !proc.killedByAm) {
10576                    proc.kill(reason, true);
10577                    killed = true;
10578                }
10579            }
10580        }
10581        return killed;
10582    }
10583
10584    @Override
10585    public void hang(final IBinder who, boolean allowRestart) {
10586        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10587                != PackageManager.PERMISSION_GRANTED) {
10588            throw new SecurityException("Requires permission "
10589                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10590        }
10591
10592        final IBinder.DeathRecipient death = new DeathRecipient() {
10593            @Override
10594            public void binderDied() {
10595                synchronized (this) {
10596                    notifyAll();
10597                }
10598            }
10599        };
10600
10601        try {
10602            who.linkToDeath(death, 0);
10603        } catch (RemoteException e) {
10604            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10605            return;
10606        }
10607
10608        synchronized (this) {
10609            Watchdog.getInstance().setAllowRestart(allowRestart);
10610            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10611            synchronized (death) {
10612                while (who.isBinderAlive()) {
10613                    try {
10614                        death.wait();
10615                    } catch (InterruptedException e) {
10616                    }
10617                }
10618            }
10619            Watchdog.getInstance().setAllowRestart(true);
10620        }
10621    }
10622
10623    @Override
10624    public void restart() {
10625        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10626                != PackageManager.PERMISSION_GRANTED) {
10627            throw new SecurityException("Requires permission "
10628                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10629        }
10630
10631        Log.i(TAG, "Sending shutdown broadcast...");
10632
10633        BroadcastReceiver br = new BroadcastReceiver() {
10634            @Override public void onReceive(Context context, Intent intent) {
10635                // Now the broadcast is done, finish up the low-level shutdown.
10636                Log.i(TAG, "Shutting down activity manager...");
10637                shutdown(10000);
10638                Log.i(TAG, "Shutdown complete, restarting!");
10639                Process.killProcess(Process.myPid());
10640                System.exit(10);
10641            }
10642        };
10643
10644        // First send the high-level shut down broadcast.
10645        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10646        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10647        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10648        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10649        mContext.sendOrderedBroadcastAsUser(intent,
10650                UserHandle.ALL, null, br, mHandler, 0, null, null);
10651        */
10652        br.onReceive(mContext, intent);
10653    }
10654
10655    private long getLowRamTimeSinceIdle(long now) {
10656        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10657    }
10658
10659    @Override
10660    public void performIdleMaintenance() {
10661        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10662                != PackageManager.PERMISSION_GRANTED) {
10663            throw new SecurityException("Requires permission "
10664                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10665        }
10666
10667        synchronized (this) {
10668            final long now = SystemClock.uptimeMillis();
10669            final long timeSinceLastIdle = now - mLastIdleTime;
10670            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10671            mLastIdleTime = now;
10672            mLowRamTimeSinceLastIdle = 0;
10673            if (mLowRamStartTime != 0) {
10674                mLowRamStartTime = now;
10675            }
10676
10677            StringBuilder sb = new StringBuilder(128);
10678            sb.append("Idle maintenance over ");
10679            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10680            sb.append(" low RAM for ");
10681            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10682            Slog.i(TAG, sb.toString());
10683
10684            // If at least 1/3 of our time since the last idle period has been spent
10685            // with RAM low, then we want to kill processes.
10686            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10687
10688            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10689                ProcessRecord proc = mLruProcesses.get(i);
10690                if (proc.notCachedSinceIdle) {
10691                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10692                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10693                        if (doKilling && proc.initialIdlePss != 0
10694                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10695                            proc.kill("idle maint (pss " + proc.lastPss
10696                                    + " from " + proc.initialIdlePss + ")", true);
10697                        }
10698                    }
10699                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10700                    proc.notCachedSinceIdle = true;
10701                    proc.initialIdlePss = 0;
10702                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10703                            isSleeping(), now);
10704                }
10705            }
10706
10707            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10708            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10709        }
10710    }
10711
10712    private void retrieveSettings() {
10713        final ContentResolver resolver = mContext.getContentResolver();
10714        String debugApp = Settings.Global.getString(
10715            resolver, Settings.Global.DEBUG_APP);
10716        boolean waitForDebugger = Settings.Global.getInt(
10717            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10718        boolean alwaysFinishActivities = Settings.Global.getInt(
10719            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10720        boolean forceRtl = Settings.Global.getInt(
10721                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10722        // Transfer any global setting for forcing RTL layout, into a System Property
10723        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10724
10725        Configuration configuration = new Configuration();
10726        Settings.System.getConfiguration(resolver, configuration);
10727        if (forceRtl) {
10728            // This will take care of setting the correct layout direction flags
10729            configuration.setLayoutDirection(configuration.locale);
10730        }
10731
10732        synchronized (this) {
10733            mDebugApp = mOrigDebugApp = debugApp;
10734            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10735            mAlwaysFinishActivities = alwaysFinishActivities;
10736            // This happens before any activities are started, so we can
10737            // change mConfiguration in-place.
10738            updateConfigurationLocked(configuration, null, false, true);
10739            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10740        }
10741    }
10742
10743    /** Loads resources after the current configuration has been set. */
10744    private void loadResourcesOnSystemReady() {
10745        final Resources res = mContext.getResources();
10746        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10747        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10748        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10749    }
10750
10751    public boolean testIsSystemReady() {
10752        // no need to synchronize(this) just to read & return the value
10753        return mSystemReady;
10754    }
10755
10756    private static File getCalledPreBootReceiversFile() {
10757        File dataDir = Environment.getDataDirectory();
10758        File systemDir = new File(dataDir, "system");
10759        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10760        return fname;
10761    }
10762
10763    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10764        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10765        File file = getCalledPreBootReceiversFile();
10766        FileInputStream fis = null;
10767        try {
10768            fis = new FileInputStream(file);
10769            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10770            int fvers = dis.readInt();
10771            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10772                String vers = dis.readUTF();
10773                String codename = dis.readUTF();
10774                String build = dis.readUTF();
10775                if (android.os.Build.VERSION.RELEASE.equals(vers)
10776                        && android.os.Build.VERSION.CODENAME.equals(codename)
10777                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10778                    int num = dis.readInt();
10779                    while (num > 0) {
10780                        num--;
10781                        String pkg = dis.readUTF();
10782                        String cls = dis.readUTF();
10783                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10784                    }
10785                }
10786            }
10787        } catch (FileNotFoundException e) {
10788        } catch (IOException e) {
10789            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10790        } finally {
10791            if (fis != null) {
10792                try {
10793                    fis.close();
10794                } catch (IOException e) {
10795                }
10796            }
10797        }
10798        return lastDoneReceivers;
10799    }
10800
10801    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10802        File file = getCalledPreBootReceiversFile();
10803        FileOutputStream fos = null;
10804        DataOutputStream dos = null;
10805        try {
10806            fos = new FileOutputStream(file);
10807            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10808            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10809            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10810            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10811            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10812            dos.writeInt(list.size());
10813            for (int i=0; i<list.size(); i++) {
10814                dos.writeUTF(list.get(i).getPackageName());
10815                dos.writeUTF(list.get(i).getClassName());
10816            }
10817        } catch (IOException e) {
10818            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10819            file.delete();
10820        } finally {
10821            FileUtils.sync(fos);
10822            if (dos != null) {
10823                try {
10824                    dos.close();
10825                } catch (IOException e) {
10826                    // TODO Auto-generated catch block
10827                    e.printStackTrace();
10828                }
10829            }
10830        }
10831    }
10832
10833    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10834            ArrayList<ComponentName> doneReceivers, int userId) {
10835        boolean waitingUpdate = false;
10836        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10837        List<ResolveInfo> ris = null;
10838        try {
10839            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10840                    intent, null, 0, userId);
10841        } catch (RemoteException e) {
10842        }
10843        if (ris != null) {
10844            for (int i=ris.size()-1; i>=0; i--) {
10845                if ((ris.get(i).activityInfo.applicationInfo.flags
10846                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10847                    ris.remove(i);
10848                }
10849            }
10850            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10851
10852            // For User 0, load the version number. When delivering to a new user, deliver
10853            // to all receivers.
10854            if (userId == UserHandle.USER_OWNER) {
10855                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10856                for (int i=0; i<ris.size(); i++) {
10857                    ActivityInfo ai = ris.get(i).activityInfo;
10858                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10859                    if (lastDoneReceivers.contains(comp)) {
10860                        // We already did the pre boot receiver for this app with the current
10861                        // platform version, so don't do it again...
10862                        ris.remove(i);
10863                        i--;
10864                        // ...however, do keep it as one that has been done, so we don't
10865                        // forget about it when rewriting the file of last done receivers.
10866                        doneReceivers.add(comp);
10867                    }
10868                }
10869            }
10870
10871            // If primary user, send broadcast to all available users, else just to userId
10872            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10873                    : new int[] { userId };
10874            for (int i = 0; i < ris.size(); i++) {
10875                ActivityInfo ai = ris.get(i).activityInfo;
10876                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10877                doneReceivers.add(comp);
10878                intent.setComponent(comp);
10879                for (int j=0; j<users.length; j++) {
10880                    IIntentReceiver finisher = null;
10881                    // On last receiver and user, set up a completion callback
10882                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10883                        finisher = new IIntentReceiver.Stub() {
10884                            public void performReceive(Intent intent, int resultCode,
10885                                    String data, Bundle extras, boolean ordered,
10886                                    boolean sticky, int sendingUser) {
10887                                // The raw IIntentReceiver interface is called
10888                                // with the AM lock held, so redispatch to
10889                                // execute our code without the lock.
10890                                mHandler.post(onFinishCallback);
10891                            }
10892                        };
10893                    }
10894                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10895                            + " for user " + users[j]);
10896                    broadcastIntentLocked(null, null, intent, null, finisher,
10897                            0, null, null, null, AppOpsManager.OP_NONE,
10898                            true, false, MY_PID, Process.SYSTEM_UID,
10899                            users[j]);
10900                    if (finisher != null) {
10901                        waitingUpdate = true;
10902                    }
10903                }
10904            }
10905        }
10906
10907        return waitingUpdate;
10908    }
10909
10910    public void systemReady(final Runnable goingCallback) {
10911        synchronized(this) {
10912            if (mSystemReady) {
10913                // If we're done calling all the receivers, run the next "boot phase" passed in
10914                // by the SystemServer
10915                if (goingCallback != null) {
10916                    goingCallback.run();
10917                }
10918                return;
10919            }
10920
10921            // Make sure we have the current profile info, since it is needed for
10922            // security checks.
10923            updateCurrentProfileIdsLocked();
10924
10925            if (mRecentTasks == null) {
10926                mRecentTasks = mTaskPersister.restoreTasksLocked();
10927                if (!mRecentTasks.isEmpty()) {
10928                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10929                }
10930                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10931                mTaskPersister.startPersisting();
10932            }
10933
10934            // Check to see if there are any update receivers to run.
10935            if (!mDidUpdate) {
10936                if (mWaitingUpdate) {
10937                    return;
10938                }
10939                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10940                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10941                    public void run() {
10942                        synchronized (ActivityManagerService.this) {
10943                            mDidUpdate = true;
10944                        }
10945                        writeLastDonePreBootReceivers(doneReceivers);
10946                        showBootMessage(mContext.getText(
10947                                R.string.android_upgrading_complete),
10948                                false);
10949                        systemReady(goingCallback);
10950                    }
10951                }, doneReceivers, UserHandle.USER_OWNER);
10952
10953                if (mWaitingUpdate) {
10954                    return;
10955                }
10956                mDidUpdate = true;
10957            }
10958
10959            mAppOpsService.systemReady();
10960            mSystemReady = true;
10961        }
10962
10963        ArrayList<ProcessRecord> procsToKill = null;
10964        synchronized(mPidsSelfLocked) {
10965            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10966                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10967                if (!isAllowedWhileBooting(proc.info)){
10968                    if (procsToKill == null) {
10969                        procsToKill = new ArrayList<ProcessRecord>();
10970                    }
10971                    procsToKill.add(proc);
10972                }
10973            }
10974        }
10975
10976        synchronized(this) {
10977            if (procsToKill != null) {
10978                for (int i=procsToKill.size()-1; i>=0; i--) {
10979                    ProcessRecord proc = procsToKill.get(i);
10980                    Slog.i(TAG, "Removing system update proc: " + proc);
10981                    removeProcessLocked(proc, true, false, "system update done");
10982                }
10983            }
10984
10985            // Now that we have cleaned up any update processes, we
10986            // are ready to start launching real processes and know that
10987            // we won't trample on them any more.
10988            mProcessesReady = true;
10989        }
10990
10991        Slog.i(TAG, "System now ready");
10992        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10993            SystemClock.uptimeMillis());
10994
10995        synchronized(this) {
10996            // Make sure we have no pre-ready processes sitting around.
10997
10998            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10999                ResolveInfo ri = mContext.getPackageManager()
11000                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11001                                STOCK_PM_FLAGS);
11002                CharSequence errorMsg = null;
11003                if (ri != null) {
11004                    ActivityInfo ai = ri.activityInfo;
11005                    ApplicationInfo app = ai.applicationInfo;
11006                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11007                        mTopAction = Intent.ACTION_FACTORY_TEST;
11008                        mTopData = null;
11009                        mTopComponent = new ComponentName(app.packageName,
11010                                ai.name);
11011                    } else {
11012                        errorMsg = mContext.getResources().getText(
11013                                com.android.internal.R.string.factorytest_not_system);
11014                    }
11015                } else {
11016                    errorMsg = mContext.getResources().getText(
11017                            com.android.internal.R.string.factorytest_no_action);
11018                }
11019                if (errorMsg != null) {
11020                    mTopAction = null;
11021                    mTopData = null;
11022                    mTopComponent = null;
11023                    Message msg = Message.obtain();
11024                    msg.what = SHOW_FACTORY_ERROR_MSG;
11025                    msg.getData().putCharSequence("msg", errorMsg);
11026                    mHandler.sendMessage(msg);
11027                }
11028            }
11029        }
11030
11031        retrieveSettings();
11032        loadResourcesOnSystemReady();
11033
11034        synchronized (this) {
11035            readGrantedUriPermissionsLocked();
11036        }
11037
11038        if (goingCallback != null) goingCallback.run();
11039
11040        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11041                Integer.toString(mCurrentUserId), mCurrentUserId);
11042        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11043                Integer.toString(mCurrentUserId), mCurrentUserId);
11044        mSystemServiceManager.startUser(mCurrentUserId);
11045
11046        synchronized (this) {
11047            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11048                try {
11049                    List apps = AppGlobals.getPackageManager().
11050                        getPersistentApplications(STOCK_PM_FLAGS);
11051                    if (apps != null) {
11052                        int N = apps.size();
11053                        int i;
11054                        for (i=0; i<N; i++) {
11055                            ApplicationInfo info
11056                                = (ApplicationInfo)apps.get(i);
11057                            if (info != null &&
11058                                    !info.packageName.equals("android")) {
11059                                addAppLocked(info, false, null /* ABI override */);
11060                            }
11061                        }
11062                    }
11063                } catch (RemoteException ex) {
11064                    // pm is in same process, this will never happen.
11065                }
11066            }
11067
11068            // Start up initial activity.
11069            mBooting = true;
11070
11071            try {
11072                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11073                    Message msg = Message.obtain();
11074                    msg.what = SHOW_UID_ERROR_MSG;
11075                    mHandler.sendMessage(msg);
11076                }
11077            } catch (RemoteException e) {
11078            }
11079
11080            long ident = Binder.clearCallingIdentity();
11081            try {
11082                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11083                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11084                        | Intent.FLAG_RECEIVER_FOREGROUND);
11085                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11086                broadcastIntentLocked(null, null, intent,
11087                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11088                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11089                intent = new Intent(Intent.ACTION_USER_STARTING);
11090                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11091                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11092                broadcastIntentLocked(null, null, intent,
11093                        null, new IIntentReceiver.Stub() {
11094                            @Override
11095                            public void performReceive(Intent intent, int resultCode, String data,
11096                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11097                                    throws RemoteException {
11098                            }
11099                        }, 0, null, null,
11100                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11101                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11102            } catch (Throwable t) {
11103                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11104            } finally {
11105                Binder.restoreCallingIdentity(ident);
11106            }
11107            mStackSupervisor.resumeTopActivitiesLocked();
11108            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11109        }
11110    }
11111
11112    private boolean makeAppCrashingLocked(ProcessRecord app,
11113            String shortMsg, String longMsg, String stackTrace) {
11114        app.crashing = true;
11115        app.crashingReport = generateProcessError(app,
11116                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11117        startAppProblemLocked(app);
11118        app.stopFreezingAllLocked();
11119        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11120    }
11121
11122    private void makeAppNotRespondingLocked(ProcessRecord app,
11123            String activity, String shortMsg, String longMsg) {
11124        app.notResponding = true;
11125        app.notRespondingReport = generateProcessError(app,
11126                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11127                activity, shortMsg, longMsg, null);
11128        startAppProblemLocked(app);
11129        app.stopFreezingAllLocked();
11130    }
11131
11132    /**
11133     * Generate a process error record, suitable for attachment to a ProcessRecord.
11134     *
11135     * @param app The ProcessRecord in which the error occurred.
11136     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11137     *                      ActivityManager.AppErrorStateInfo
11138     * @param activity The activity associated with the crash, if known.
11139     * @param shortMsg Short message describing the crash.
11140     * @param longMsg Long message describing the crash.
11141     * @param stackTrace Full crash stack trace, may be null.
11142     *
11143     * @return Returns a fully-formed AppErrorStateInfo record.
11144     */
11145    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11146            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11147        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11148
11149        report.condition = condition;
11150        report.processName = app.processName;
11151        report.pid = app.pid;
11152        report.uid = app.info.uid;
11153        report.tag = activity;
11154        report.shortMsg = shortMsg;
11155        report.longMsg = longMsg;
11156        report.stackTrace = stackTrace;
11157
11158        return report;
11159    }
11160
11161    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11162        synchronized (this) {
11163            app.crashing = false;
11164            app.crashingReport = null;
11165            app.notResponding = false;
11166            app.notRespondingReport = null;
11167            if (app.anrDialog == fromDialog) {
11168                app.anrDialog = null;
11169            }
11170            if (app.waitDialog == fromDialog) {
11171                app.waitDialog = null;
11172            }
11173            if (app.pid > 0 && app.pid != MY_PID) {
11174                handleAppCrashLocked(app, null, null, null);
11175                app.kill("user request after error", true);
11176            }
11177        }
11178    }
11179
11180    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11181            String stackTrace) {
11182        long now = SystemClock.uptimeMillis();
11183
11184        Long crashTime;
11185        if (!app.isolated) {
11186            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11187        } else {
11188            crashTime = null;
11189        }
11190        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11191            // This process loses!
11192            Slog.w(TAG, "Process " + app.info.processName
11193                    + " has crashed too many times: killing!");
11194            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11195                    app.userId, app.info.processName, app.uid);
11196            mStackSupervisor.handleAppCrashLocked(app);
11197            if (!app.persistent) {
11198                // We don't want to start this process again until the user
11199                // explicitly does so...  but for persistent process, we really
11200                // need to keep it running.  If a persistent process is actually
11201                // repeatedly crashing, then badness for everyone.
11202                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11203                        app.info.processName);
11204                if (!app.isolated) {
11205                    // XXX We don't have a way to mark isolated processes
11206                    // as bad, since they don't have a peristent identity.
11207                    mBadProcesses.put(app.info.processName, app.uid,
11208                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11209                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11210                }
11211                app.bad = true;
11212                app.removed = true;
11213                // Don't let services in this process be restarted and potentially
11214                // annoy the user repeatedly.  Unless it is persistent, since those
11215                // processes run critical code.
11216                removeProcessLocked(app, false, false, "crash");
11217                mStackSupervisor.resumeTopActivitiesLocked();
11218                return false;
11219            }
11220            mStackSupervisor.resumeTopActivitiesLocked();
11221        } else {
11222            mStackSupervisor.finishTopRunningActivityLocked(app);
11223        }
11224
11225        // Bump up the crash count of any services currently running in the proc.
11226        for (int i=app.services.size()-1; i>=0; i--) {
11227            // Any services running in the application need to be placed
11228            // back in the pending list.
11229            ServiceRecord sr = app.services.valueAt(i);
11230            sr.crashCount++;
11231        }
11232
11233        // If the crashing process is what we consider to be the "home process" and it has been
11234        // replaced by a third-party app, clear the package preferred activities from packages
11235        // with a home activity running in the process to prevent a repeatedly crashing app
11236        // from blocking the user to manually clear the list.
11237        final ArrayList<ActivityRecord> activities = app.activities;
11238        if (app == mHomeProcess && activities.size() > 0
11239                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11240            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11241                final ActivityRecord r = activities.get(activityNdx);
11242                if (r.isHomeActivity()) {
11243                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11244                    try {
11245                        ActivityThread.getPackageManager()
11246                                .clearPackagePreferredActivities(r.packageName);
11247                    } catch (RemoteException c) {
11248                        // pm is in same process, this will never happen.
11249                    }
11250                }
11251            }
11252        }
11253
11254        if (!app.isolated) {
11255            // XXX Can't keep track of crash times for isolated processes,
11256            // because they don't have a perisistent identity.
11257            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11258        }
11259
11260        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11261        return true;
11262    }
11263
11264    void startAppProblemLocked(ProcessRecord app) {
11265        // If this app is not running under the current user, then we
11266        // can't give it a report button because that would require
11267        // launching the report UI under a different user.
11268        app.errorReportReceiver = null;
11269
11270        for (int userId : mCurrentProfileIds) {
11271            if (app.userId == userId) {
11272                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11273                        mContext, app.info.packageName, app.info.flags);
11274            }
11275        }
11276        skipCurrentReceiverLocked(app);
11277    }
11278
11279    void skipCurrentReceiverLocked(ProcessRecord app) {
11280        for (BroadcastQueue queue : mBroadcastQueues) {
11281            queue.skipCurrentReceiverLocked(app);
11282        }
11283    }
11284
11285    /**
11286     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11287     * The application process will exit immediately after this call returns.
11288     * @param app object of the crashing app, null for the system server
11289     * @param crashInfo describing the exception
11290     */
11291    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11292        ProcessRecord r = findAppProcess(app, "Crash");
11293        final String processName = app == null ? "system_server"
11294                : (r == null ? "unknown" : r.processName);
11295
11296        handleApplicationCrashInner("crash", r, processName, crashInfo);
11297    }
11298
11299    /* Native crash reporting uses this inner version because it needs to be somewhat
11300     * decoupled from the AM-managed cleanup lifecycle
11301     */
11302    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11303            ApplicationErrorReport.CrashInfo crashInfo) {
11304        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11305                UserHandle.getUserId(Binder.getCallingUid()), processName,
11306                r == null ? -1 : r.info.flags,
11307                crashInfo.exceptionClassName,
11308                crashInfo.exceptionMessage,
11309                crashInfo.throwFileName,
11310                crashInfo.throwLineNumber);
11311
11312        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11313
11314        crashApplication(r, crashInfo);
11315    }
11316
11317    public void handleApplicationStrictModeViolation(
11318            IBinder app,
11319            int violationMask,
11320            StrictMode.ViolationInfo info) {
11321        ProcessRecord r = findAppProcess(app, "StrictMode");
11322        if (r == null) {
11323            return;
11324        }
11325
11326        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11327            Integer stackFingerprint = info.hashCode();
11328            boolean logIt = true;
11329            synchronized (mAlreadyLoggedViolatedStacks) {
11330                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11331                    logIt = false;
11332                    // TODO: sub-sample into EventLog for these, with
11333                    // the info.durationMillis?  Then we'd get
11334                    // the relative pain numbers, without logging all
11335                    // the stack traces repeatedly.  We'd want to do
11336                    // likewise in the client code, which also does
11337                    // dup suppression, before the Binder call.
11338                } else {
11339                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11340                        mAlreadyLoggedViolatedStacks.clear();
11341                    }
11342                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11343                }
11344            }
11345            if (logIt) {
11346                logStrictModeViolationToDropBox(r, info);
11347            }
11348        }
11349
11350        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11351            AppErrorResult result = new AppErrorResult();
11352            synchronized (this) {
11353                final long origId = Binder.clearCallingIdentity();
11354
11355                Message msg = Message.obtain();
11356                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11357                HashMap<String, Object> data = new HashMap<String, Object>();
11358                data.put("result", result);
11359                data.put("app", r);
11360                data.put("violationMask", violationMask);
11361                data.put("info", info);
11362                msg.obj = data;
11363                mHandler.sendMessage(msg);
11364
11365                Binder.restoreCallingIdentity(origId);
11366            }
11367            int res = result.get();
11368            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11369        }
11370    }
11371
11372    // Depending on the policy in effect, there could be a bunch of
11373    // these in quick succession so we try to batch these together to
11374    // minimize disk writes, number of dropbox entries, and maximize
11375    // compression, by having more fewer, larger records.
11376    private void logStrictModeViolationToDropBox(
11377            ProcessRecord process,
11378            StrictMode.ViolationInfo info) {
11379        if (info == null) {
11380            return;
11381        }
11382        final boolean isSystemApp = process == null ||
11383                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11384                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11385        final String processName = process == null ? "unknown" : process.processName;
11386        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11387        final DropBoxManager dbox = (DropBoxManager)
11388                mContext.getSystemService(Context.DROPBOX_SERVICE);
11389
11390        // Exit early if the dropbox isn't configured to accept this report type.
11391        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11392
11393        boolean bufferWasEmpty;
11394        boolean needsFlush;
11395        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11396        synchronized (sb) {
11397            bufferWasEmpty = sb.length() == 0;
11398            appendDropBoxProcessHeaders(process, processName, sb);
11399            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11400            sb.append("System-App: ").append(isSystemApp).append("\n");
11401            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11402            if (info.violationNumThisLoop != 0) {
11403                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11404            }
11405            if (info.numAnimationsRunning != 0) {
11406                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11407            }
11408            if (info.broadcastIntentAction != null) {
11409                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11410            }
11411            if (info.durationMillis != -1) {
11412                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11413            }
11414            if (info.numInstances != -1) {
11415                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11416            }
11417            if (info.tags != null) {
11418                for (String tag : info.tags) {
11419                    sb.append("Span-Tag: ").append(tag).append("\n");
11420                }
11421            }
11422            sb.append("\n");
11423            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11424                sb.append(info.crashInfo.stackTrace);
11425            }
11426            sb.append("\n");
11427
11428            // Only buffer up to ~64k.  Various logging bits truncate
11429            // things at 128k.
11430            needsFlush = (sb.length() > 64 * 1024);
11431        }
11432
11433        // Flush immediately if the buffer's grown too large, or this
11434        // is a non-system app.  Non-system apps are isolated with a
11435        // different tag & policy and not batched.
11436        //
11437        // Batching is useful during internal testing with
11438        // StrictMode settings turned up high.  Without batching,
11439        // thousands of separate files could be created on boot.
11440        if (!isSystemApp || needsFlush) {
11441            new Thread("Error dump: " + dropboxTag) {
11442                @Override
11443                public void run() {
11444                    String report;
11445                    synchronized (sb) {
11446                        report = sb.toString();
11447                        sb.delete(0, sb.length());
11448                        sb.trimToSize();
11449                    }
11450                    if (report.length() != 0) {
11451                        dbox.addText(dropboxTag, report);
11452                    }
11453                }
11454            }.start();
11455            return;
11456        }
11457
11458        // System app batching:
11459        if (!bufferWasEmpty) {
11460            // An existing dropbox-writing thread is outstanding, so
11461            // we don't need to start it up.  The existing thread will
11462            // catch the buffer appends we just did.
11463            return;
11464        }
11465
11466        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11467        // (After this point, we shouldn't access AMS internal data structures.)
11468        new Thread("Error dump: " + dropboxTag) {
11469            @Override
11470            public void run() {
11471                // 5 second sleep to let stacks arrive and be batched together
11472                try {
11473                    Thread.sleep(5000);  // 5 seconds
11474                } catch (InterruptedException e) {}
11475
11476                String errorReport;
11477                synchronized (mStrictModeBuffer) {
11478                    errorReport = mStrictModeBuffer.toString();
11479                    if (errorReport.length() == 0) {
11480                        return;
11481                    }
11482                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11483                    mStrictModeBuffer.trimToSize();
11484                }
11485                dbox.addText(dropboxTag, errorReport);
11486            }
11487        }.start();
11488    }
11489
11490    /**
11491     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11492     * @param app object of the crashing app, null for the system server
11493     * @param tag reported by the caller
11494     * @param system whether this wtf is coming from the system
11495     * @param crashInfo describing the context of the error
11496     * @return true if the process should exit immediately (WTF is fatal)
11497     */
11498    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11499            final ApplicationErrorReport.CrashInfo crashInfo) {
11500        final ProcessRecord r = findAppProcess(app, "WTF");
11501        final String processName = app == null ? "system_server"
11502                : (r == null ? "unknown" : r.processName);
11503
11504        EventLog.writeEvent(EventLogTags.AM_WTF,
11505                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11506                processName,
11507                r == null ? -1 : r.info.flags,
11508                tag, crashInfo.exceptionMessage);
11509
11510        if (system) {
11511            // If this is coming from the system, we could very well have low-level
11512            // system locks held, so we want to do this all asynchronously.  And we
11513            // never want this to become fatal, so there is that too.
11514            mHandler.post(new Runnable() {
11515                @Override public void run() {
11516                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11517                            crashInfo);
11518                }
11519            });
11520            return false;
11521        }
11522
11523        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11524
11525        if (r != null && r.pid != Process.myPid() &&
11526                Settings.Global.getInt(mContext.getContentResolver(),
11527                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11528            crashApplication(r, crashInfo);
11529            return true;
11530        } else {
11531            return false;
11532        }
11533    }
11534
11535    /**
11536     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11537     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11538     */
11539    private ProcessRecord findAppProcess(IBinder app, String reason) {
11540        if (app == null) {
11541            return null;
11542        }
11543
11544        synchronized (this) {
11545            final int NP = mProcessNames.getMap().size();
11546            for (int ip=0; ip<NP; ip++) {
11547                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11548                final int NA = apps.size();
11549                for (int ia=0; ia<NA; ia++) {
11550                    ProcessRecord p = apps.valueAt(ia);
11551                    if (p.thread != null && p.thread.asBinder() == app) {
11552                        return p;
11553                    }
11554                }
11555            }
11556
11557            Slog.w(TAG, "Can't find mystery application for " + reason
11558                    + " from pid=" + Binder.getCallingPid()
11559                    + " uid=" + Binder.getCallingUid() + ": " + app);
11560            return null;
11561        }
11562    }
11563
11564    /**
11565     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11566     * to append various headers to the dropbox log text.
11567     */
11568    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11569            StringBuilder sb) {
11570        // Watchdog thread ends up invoking this function (with
11571        // a null ProcessRecord) to add the stack file to dropbox.
11572        // Do not acquire a lock on this (am) in such cases, as it
11573        // could cause a potential deadlock, if and when watchdog
11574        // is invoked due to unavailability of lock on am and it
11575        // would prevent watchdog from killing system_server.
11576        if (process == null) {
11577            sb.append("Process: ").append(processName).append("\n");
11578            return;
11579        }
11580        // Note: ProcessRecord 'process' is guarded by the service
11581        // instance.  (notably process.pkgList, which could otherwise change
11582        // concurrently during execution of this method)
11583        synchronized (this) {
11584            sb.append("Process: ").append(processName).append("\n");
11585            int flags = process.info.flags;
11586            IPackageManager pm = AppGlobals.getPackageManager();
11587            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11588            for (int ip=0; ip<process.pkgList.size(); ip++) {
11589                String pkg = process.pkgList.keyAt(ip);
11590                sb.append("Package: ").append(pkg);
11591                try {
11592                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11593                    if (pi != null) {
11594                        sb.append(" v").append(pi.versionCode);
11595                        if (pi.versionName != null) {
11596                            sb.append(" (").append(pi.versionName).append(")");
11597                        }
11598                    }
11599                } catch (RemoteException e) {
11600                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11601                }
11602                sb.append("\n");
11603            }
11604        }
11605    }
11606
11607    private static String processClass(ProcessRecord process) {
11608        if (process == null || process.pid == MY_PID) {
11609            return "system_server";
11610        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11611            return "system_app";
11612        } else {
11613            return "data_app";
11614        }
11615    }
11616
11617    /**
11618     * Write a description of an error (crash, WTF, ANR) to the drop box.
11619     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11620     * @param process which caused the error, null means the system server
11621     * @param activity which triggered the error, null if unknown
11622     * @param parent activity related to the error, null if unknown
11623     * @param subject line related to the error, null if absent
11624     * @param report in long form describing the error, null if absent
11625     * @param logFile to include in the report, null if none
11626     * @param crashInfo giving an application stack trace, null if absent
11627     */
11628    public void addErrorToDropBox(String eventType,
11629            ProcessRecord process, String processName, ActivityRecord activity,
11630            ActivityRecord parent, String subject,
11631            final String report, final File logFile,
11632            final ApplicationErrorReport.CrashInfo crashInfo) {
11633        // NOTE -- this must never acquire the ActivityManagerService lock,
11634        // otherwise the watchdog may be prevented from resetting the system.
11635
11636        final String dropboxTag = processClass(process) + "_" + eventType;
11637        final DropBoxManager dbox = (DropBoxManager)
11638                mContext.getSystemService(Context.DROPBOX_SERVICE);
11639
11640        // Exit early if the dropbox isn't configured to accept this report type.
11641        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11642
11643        final StringBuilder sb = new StringBuilder(1024);
11644        appendDropBoxProcessHeaders(process, processName, sb);
11645        if (activity != null) {
11646            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11647        }
11648        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11649            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11650        }
11651        if (parent != null && parent != activity) {
11652            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11653        }
11654        if (subject != null) {
11655            sb.append("Subject: ").append(subject).append("\n");
11656        }
11657        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11658        if (Debug.isDebuggerConnected()) {
11659            sb.append("Debugger: Connected\n");
11660        }
11661        sb.append("\n");
11662
11663        // Do the rest in a worker thread to avoid blocking the caller on I/O
11664        // (After this point, we shouldn't access AMS internal data structures.)
11665        Thread worker = new Thread("Error dump: " + dropboxTag) {
11666            @Override
11667            public void run() {
11668                if (report != null) {
11669                    sb.append(report);
11670                }
11671                if (logFile != null) {
11672                    try {
11673                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11674                                    "\n\n[[TRUNCATED]]"));
11675                    } catch (IOException e) {
11676                        Slog.e(TAG, "Error reading " + logFile, e);
11677                    }
11678                }
11679                if (crashInfo != null && crashInfo.stackTrace != null) {
11680                    sb.append(crashInfo.stackTrace);
11681                }
11682
11683                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11684                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11685                if (lines > 0) {
11686                    sb.append("\n");
11687
11688                    // Merge several logcat streams, and take the last N lines
11689                    InputStreamReader input = null;
11690                    try {
11691                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11692                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11693                                "-b", "crash",
11694                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11695
11696                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11697                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11698                        input = new InputStreamReader(logcat.getInputStream());
11699
11700                        int num;
11701                        char[] buf = new char[8192];
11702                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11703                    } catch (IOException e) {
11704                        Slog.e(TAG, "Error running logcat", e);
11705                    } finally {
11706                        if (input != null) try { input.close(); } catch (IOException e) {}
11707                    }
11708                }
11709
11710                dbox.addText(dropboxTag, sb.toString());
11711            }
11712        };
11713
11714        if (process == null) {
11715            // If process is null, we are being called from some internal code
11716            // and may be about to die -- run this synchronously.
11717            worker.run();
11718        } else {
11719            worker.start();
11720        }
11721    }
11722
11723    /**
11724     * Bring up the "unexpected error" dialog box for a crashing app.
11725     * Deal with edge cases (intercepts from instrumented applications,
11726     * ActivityController, error intent receivers, that sort of thing).
11727     * @param r the application crashing
11728     * @param crashInfo describing the failure
11729     */
11730    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11731        long timeMillis = System.currentTimeMillis();
11732        String shortMsg = crashInfo.exceptionClassName;
11733        String longMsg = crashInfo.exceptionMessage;
11734        String stackTrace = crashInfo.stackTrace;
11735        if (shortMsg != null && longMsg != null) {
11736            longMsg = shortMsg + ": " + longMsg;
11737        } else if (shortMsg != null) {
11738            longMsg = shortMsg;
11739        }
11740
11741        AppErrorResult result = new AppErrorResult();
11742        synchronized (this) {
11743            if (mController != null) {
11744                try {
11745                    String name = r != null ? r.processName : null;
11746                    int pid = r != null ? r.pid : Binder.getCallingPid();
11747                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11748                    if (!mController.appCrashed(name, pid,
11749                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11750                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11751                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11752                            Slog.w(TAG, "Skip killing native crashed app " + name
11753                                    + "(" + pid + ") during testing");
11754                        } else {
11755                            Slog.w(TAG, "Force-killing crashed app " + name
11756                                    + " at watcher's request");
11757                            if (r != null) {
11758                                r.kill("crash", true);
11759                            } else {
11760                                // Huh.
11761                                Process.killProcess(pid);
11762                                Process.killProcessGroup(uid, pid);
11763                            }
11764                        }
11765                        return;
11766                    }
11767                } catch (RemoteException e) {
11768                    mController = null;
11769                    Watchdog.getInstance().setActivityController(null);
11770                }
11771            }
11772
11773            final long origId = Binder.clearCallingIdentity();
11774
11775            // If this process is running instrumentation, finish it.
11776            if (r != null && r.instrumentationClass != null) {
11777                Slog.w(TAG, "Error in app " + r.processName
11778                      + " running instrumentation " + r.instrumentationClass + ":");
11779                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11780                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11781                Bundle info = new Bundle();
11782                info.putString("shortMsg", shortMsg);
11783                info.putString("longMsg", longMsg);
11784                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11785                Binder.restoreCallingIdentity(origId);
11786                return;
11787            }
11788
11789            // If we can't identify the process or it's already exceeded its crash quota,
11790            // quit right away without showing a crash dialog.
11791            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11792                Binder.restoreCallingIdentity(origId);
11793                return;
11794            }
11795
11796            Message msg = Message.obtain();
11797            msg.what = SHOW_ERROR_MSG;
11798            HashMap data = new HashMap();
11799            data.put("result", result);
11800            data.put("app", r);
11801            msg.obj = data;
11802            mHandler.sendMessage(msg);
11803
11804            Binder.restoreCallingIdentity(origId);
11805        }
11806
11807        int res = result.get();
11808
11809        Intent appErrorIntent = null;
11810        synchronized (this) {
11811            if (r != null && !r.isolated) {
11812                // XXX Can't keep track of crash time for isolated processes,
11813                // since they don't have a persistent identity.
11814                mProcessCrashTimes.put(r.info.processName, r.uid,
11815                        SystemClock.uptimeMillis());
11816            }
11817            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11818                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11819            }
11820        }
11821
11822        if (appErrorIntent != null) {
11823            try {
11824                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11825            } catch (ActivityNotFoundException e) {
11826                Slog.w(TAG, "bug report receiver dissappeared", e);
11827            }
11828        }
11829    }
11830
11831    Intent createAppErrorIntentLocked(ProcessRecord r,
11832            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11833        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11834        if (report == null) {
11835            return null;
11836        }
11837        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11838        result.setComponent(r.errorReportReceiver);
11839        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11840        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11841        return result;
11842    }
11843
11844    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11845            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11846        if (r.errorReportReceiver == null) {
11847            return null;
11848        }
11849
11850        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11851            return null;
11852        }
11853
11854        ApplicationErrorReport report = new ApplicationErrorReport();
11855        report.packageName = r.info.packageName;
11856        report.installerPackageName = r.errorReportReceiver.getPackageName();
11857        report.processName = r.processName;
11858        report.time = timeMillis;
11859        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11860
11861        if (r.crashing || r.forceCrashReport) {
11862            report.type = ApplicationErrorReport.TYPE_CRASH;
11863            report.crashInfo = crashInfo;
11864        } else if (r.notResponding) {
11865            report.type = ApplicationErrorReport.TYPE_ANR;
11866            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11867
11868            report.anrInfo.activity = r.notRespondingReport.tag;
11869            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11870            report.anrInfo.info = r.notRespondingReport.longMsg;
11871        }
11872
11873        return report;
11874    }
11875
11876    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11877        enforceNotIsolatedCaller("getProcessesInErrorState");
11878        // assume our apps are happy - lazy create the list
11879        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11880
11881        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11882                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11883        int userId = UserHandle.getUserId(Binder.getCallingUid());
11884
11885        synchronized (this) {
11886
11887            // iterate across all processes
11888            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11889                ProcessRecord app = mLruProcesses.get(i);
11890                if (!allUsers && app.userId != userId) {
11891                    continue;
11892                }
11893                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11894                    // This one's in trouble, so we'll generate a report for it
11895                    // crashes are higher priority (in case there's a crash *and* an anr)
11896                    ActivityManager.ProcessErrorStateInfo report = null;
11897                    if (app.crashing) {
11898                        report = app.crashingReport;
11899                    } else if (app.notResponding) {
11900                        report = app.notRespondingReport;
11901                    }
11902
11903                    if (report != null) {
11904                        if (errList == null) {
11905                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11906                        }
11907                        errList.add(report);
11908                    } else {
11909                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11910                                " crashing = " + app.crashing +
11911                                " notResponding = " + app.notResponding);
11912                    }
11913                }
11914            }
11915        }
11916
11917        return errList;
11918    }
11919
11920    static int procStateToImportance(int procState, int memAdj,
11921            ActivityManager.RunningAppProcessInfo currApp) {
11922        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11923        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11924            currApp.lru = memAdj;
11925        } else {
11926            currApp.lru = 0;
11927        }
11928        return imp;
11929    }
11930
11931    private void fillInProcMemInfo(ProcessRecord app,
11932            ActivityManager.RunningAppProcessInfo outInfo) {
11933        outInfo.pid = app.pid;
11934        outInfo.uid = app.info.uid;
11935        if (mHeavyWeightProcess == app) {
11936            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11937        }
11938        if (app.persistent) {
11939            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11940        }
11941        if (app.activities.size() > 0) {
11942            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11943        }
11944        outInfo.lastTrimLevel = app.trimMemoryLevel;
11945        int adj = app.curAdj;
11946        int procState = app.curProcState;
11947        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11948        outInfo.importanceReasonCode = app.adjTypeCode;
11949        outInfo.processState = app.curProcState;
11950    }
11951
11952    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11953        enforceNotIsolatedCaller("getRunningAppProcesses");
11954        // Lazy instantiation of list
11955        List<ActivityManager.RunningAppProcessInfo> runList = null;
11956        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11957                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11958        int userId = UserHandle.getUserId(Binder.getCallingUid());
11959        synchronized (this) {
11960            // Iterate across all processes
11961            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11962                ProcessRecord app = mLruProcesses.get(i);
11963                if (!allUsers && app.userId != userId) {
11964                    continue;
11965                }
11966                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11967                    // Generate process state info for running application
11968                    ActivityManager.RunningAppProcessInfo currApp =
11969                        new ActivityManager.RunningAppProcessInfo(app.processName,
11970                                app.pid, app.getPackageList());
11971                    fillInProcMemInfo(app, currApp);
11972                    if (app.adjSource instanceof ProcessRecord) {
11973                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11974                        currApp.importanceReasonImportance =
11975                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11976                                        app.adjSourceProcState);
11977                    } else if (app.adjSource instanceof ActivityRecord) {
11978                        ActivityRecord r = (ActivityRecord)app.adjSource;
11979                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11980                    }
11981                    if (app.adjTarget instanceof ComponentName) {
11982                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11983                    }
11984                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11985                    //        + " lru=" + currApp.lru);
11986                    if (runList == null) {
11987                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11988                    }
11989                    runList.add(currApp);
11990                }
11991            }
11992        }
11993        return runList;
11994    }
11995
11996    public List<ApplicationInfo> getRunningExternalApplications() {
11997        enforceNotIsolatedCaller("getRunningExternalApplications");
11998        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11999        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12000        if (runningApps != null && runningApps.size() > 0) {
12001            Set<String> extList = new HashSet<String>();
12002            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12003                if (app.pkgList != null) {
12004                    for (String pkg : app.pkgList) {
12005                        extList.add(pkg);
12006                    }
12007                }
12008            }
12009            IPackageManager pm = AppGlobals.getPackageManager();
12010            for (String pkg : extList) {
12011                try {
12012                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12013                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12014                        retList.add(info);
12015                    }
12016                } catch (RemoteException e) {
12017                }
12018            }
12019        }
12020        return retList;
12021    }
12022
12023    @Override
12024    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12025        enforceNotIsolatedCaller("getMyMemoryState");
12026        synchronized (this) {
12027            ProcessRecord proc;
12028            synchronized (mPidsSelfLocked) {
12029                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12030            }
12031            fillInProcMemInfo(proc, outInfo);
12032        }
12033    }
12034
12035    @Override
12036    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12037        if (checkCallingPermission(android.Manifest.permission.DUMP)
12038                != PackageManager.PERMISSION_GRANTED) {
12039            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12040                    + Binder.getCallingPid()
12041                    + ", uid=" + Binder.getCallingUid()
12042                    + " without permission "
12043                    + android.Manifest.permission.DUMP);
12044            return;
12045        }
12046
12047        boolean dumpAll = false;
12048        boolean dumpClient = false;
12049        String dumpPackage = null;
12050
12051        int opti = 0;
12052        while (opti < args.length) {
12053            String opt = args[opti];
12054            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12055                break;
12056            }
12057            opti++;
12058            if ("-a".equals(opt)) {
12059                dumpAll = true;
12060            } else if ("-c".equals(opt)) {
12061                dumpClient = true;
12062            } else if ("-h".equals(opt)) {
12063                pw.println("Activity manager dump options:");
12064                pw.println("  [-a] [-c] [-h] [cmd] ...");
12065                pw.println("  cmd may be one of:");
12066                pw.println("    a[ctivities]: activity stack state");
12067                pw.println("    r[recents]: recent activities state");
12068                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12069                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12070                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12071                pw.println("    o[om]: out of memory management");
12072                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12073                pw.println("    provider [COMP_SPEC]: provider client-side state");
12074                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12075                pw.println("    service [COMP_SPEC]: service client-side state");
12076                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12077                pw.println("    all: dump all activities");
12078                pw.println("    top: dump the top activity");
12079                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12080                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12081                pw.println("    a partial substring in a component name, a");
12082                pw.println("    hex object identifier.");
12083                pw.println("  -a: include all available server state.");
12084                pw.println("  -c: include client state.");
12085                return;
12086            } else {
12087                pw.println("Unknown argument: " + opt + "; use -h for help");
12088            }
12089        }
12090
12091        long origId = Binder.clearCallingIdentity();
12092        boolean more = false;
12093        // Is the caller requesting to dump a particular piece of data?
12094        if (opti < args.length) {
12095            String cmd = args[opti];
12096            opti++;
12097            if ("activities".equals(cmd) || "a".equals(cmd)) {
12098                synchronized (this) {
12099                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12100                }
12101            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12102                synchronized (this) {
12103                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12104                }
12105            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12106                String[] newArgs;
12107                String name;
12108                if (opti >= args.length) {
12109                    name = null;
12110                    newArgs = EMPTY_STRING_ARRAY;
12111                } else {
12112                    name = args[opti];
12113                    opti++;
12114                    newArgs = new String[args.length - opti];
12115                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12116                            args.length - opti);
12117                }
12118                synchronized (this) {
12119                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12120                }
12121            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12122                String[] newArgs;
12123                String name;
12124                if (opti >= args.length) {
12125                    name = null;
12126                    newArgs = EMPTY_STRING_ARRAY;
12127                } else {
12128                    name = args[opti];
12129                    opti++;
12130                    newArgs = new String[args.length - opti];
12131                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12132                            args.length - opti);
12133                }
12134                synchronized (this) {
12135                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12136                }
12137            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12138                String[] newArgs;
12139                String name;
12140                if (opti >= args.length) {
12141                    name = null;
12142                    newArgs = EMPTY_STRING_ARRAY;
12143                } else {
12144                    name = args[opti];
12145                    opti++;
12146                    newArgs = new String[args.length - opti];
12147                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12148                            args.length - opti);
12149                }
12150                synchronized (this) {
12151                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12152                }
12153            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12154                synchronized (this) {
12155                    dumpOomLocked(fd, pw, args, opti, true);
12156                }
12157            } else if ("provider".equals(cmd)) {
12158                String[] newArgs;
12159                String name;
12160                if (opti >= args.length) {
12161                    name = null;
12162                    newArgs = EMPTY_STRING_ARRAY;
12163                } else {
12164                    name = args[opti];
12165                    opti++;
12166                    newArgs = new String[args.length - opti];
12167                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12168                }
12169                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12170                    pw.println("No providers match: " + name);
12171                    pw.println("Use -h for help.");
12172                }
12173            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12174                synchronized (this) {
12175                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12176                }
12177            } else if ("service".equals(cmd)) {
12178                String[] newArgs;
12179                String name;
12180                if (opti >= args.length) {
12181                    name = null;
12182                    newArgs = EMPTY_STRING_ARRAY;
12183                } else {
12184                    name = args[opti];
12185                    opti++;
12186                    newArgs = new String[args.length - opti];
12187                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12188                            args.length - opti);
12189                }
12190                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12191                    pw.println("No services match: " + name);
12192                    pw.println("Use -h for help.");
12193                }
12194            } else if ("package".equals(cmd)) {
12195                String[] newArgs;
12196                if (opti >= args.length) {
12197                    pw.println("package: no package name specified");
12198                    pw.println("Use -h for help.");
12199                } else {
12200                    dumpPackage = args[opti];
12201                    opti++;
12202                    newArgs = new String[args.length - opti];
12203                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12204                            args.length - opti);
12205                    args = newArgs;
12206                    opti = 0;
12207                    more = true;
12208                }
12209            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12210                synchronized (this) {
12211                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12212                }
12213            } else {
12214                // Dumping a single activity?
12215                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12216                    pw.println("Bad activity command, or no activities match: " + cmd);
12217                    pw.println("Use -h for help.");
12218                }
12219            }
12220            if (!more) {
12221                Binder.restoreCallingIdentity(origId);
12222                return;
12223            }
12224        }
12225
12226        // No piece of data specified, dump everything.
12227        synchronized (this) {
12228            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12229            pw.println();
12230            if (dumpAll) {
12231                pw.println("-------------------------------------------------------------------------------");
12232            }
12233            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12234            pw.println();
12235            if (dumpAll) {
12236                pw.println("-------------------------------------------------------------------------------");
12237            }
12238            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12239            pw.println();
12240            if (dumpAll) {
12241                pw.println("-------------------------------------------------------------------------------");
12242            }
12243            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12244            pw.println();
12245            if (dumpAll) {
12246                pw.println("-------------------------------------------------------------------------------");
12247            }
12248            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12249            pw.println();
12250            if (dumpAll) {
12251                pw.println("-------------------------------------------------------------------------------");
12252            }
12253            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12254            pw.println();
12255            if (dumpAll) {
12256                pw.println("-------------------------------------------------------------------------------");
12257            }
12258            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12259        }
12260        Binder.restoreCallingIdentity(origId);
12261    }
12262
12263    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12264            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12265        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12266
12267        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12268                dumpPackage);
12269        boolean needSep = printedAnything;
12270
12271        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12272                dumpPackage, needSep, "  mFocusedActivity: ");
12273        if (printed) {
12274            printedAnything = true;
12275            needSep = false;
12276        }
12277
12278        if (dumpPackage == null) {
12279            if (needSep) {
12280                pw.println();
12281            }
12282            needSep = true;
12283            printedAnything = true;
12284            mStackSupervisor.dump(pw, "  ");
12285        }
12286
12287        if (!printedAnything) {
12288            pw.println("  (nothing)");
12289        }
12290    }
12291
12292    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12293            int opti, boolean dumpAll, String dumpPackage) {
12294        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12295
12296        boolean printedAnything = false;
12297
12298        if (mRecentTasks.size() > 0) {
12299            boolean printedHeader = false;
12300
12301            final int N = mRecentTasks.size();
12302            for (int i=0; i<N; i++) {
12303                TaskRecord tr = mRecentTasks.get(i);
12304                if (dumpPackage != null) {
12305                    if (tr.realActivity == null ||
12306                            !dumpPackage.equals(tr.realActivity)) {
12307                        continue;
12308                    }
12309                }
12310                if (!printedHeader) {
12311                    pw.println("  Recent tasks:");
12312                    printedHeader = true;
12313                    printedAnything = true;
12314                }
12315                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12316                        pw.println(tr);
12317                if (dumpAll) {
12318                    mRecentTasks.get(i).dump(pw, "    ");
12319                }
12320            }
12321        }
12322
12323        if (!printedAnything) {
12324            pw.println("  (nothing)");
12325        }
12326    }
12327
12328    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12329            int opti, boolean dumpAll, String dumpPackage) {
12330        boolean needSep = false;
12331        boolean printedAnything = false;
12332        int numPers = 0;
12333
12334        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12335
12336        if (dumpAll) {
12337            final int NP = mProcessNames.getMap().size();
12338            for (int ip=0; ip<NP; ip++) {
12339                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12340                final int NA = procs.size();
12341                for (int ia=0; ia<NA; ia++) {
12342                    ProcessRecord r = procs.valueAt(ia);
12343                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12344                        continue;
12345                    }
12346                    if (!needSep) {
12347                        pw.println("  All known processes:");
12348                        needSep = true;
12349                        printedAnything = true;
12350                    }
12351                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12352                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12353                        pw.print(" "); pw.println(r);
12354                    r.dump(pw, "    ");
12355                    if (r.persistent) {
12356                        numPers++;
12357                    }
12358                }
12359            }
12360        }
12361
12362        if (mIsolatedProcesses.size() > 0) {
12363            boolean printed = false;
12364            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12365                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12366                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12367                    continue;
12368                }
12369                if (!printed) {
12370                    if (needSep) {
12371                        pw.println();
12372                    }
12373                    pw.println("  Isolated process list (sorted by uid):");
12374                    printedAnything = true;
12375                    printed = true;
12376                    needSep = true;
12377                }
12378                pw.println(String.format("%sIsolated #%2d: %s",
12379                        "    ", i, r.toString()));
12380            }
12381        }
12382
12383        if (mLruProcesses.size() > 0) {
12384            if (needSep) {
12385                pw.println();
12386            }
12387            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12388                    pw.print(" total, non-act at ");
12389                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12390                    pw.print(", non-svc at ");
12391                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12392                    pw.println("):");
12393            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12394            needSep = true;
12395            printedAnything = true;
12396        }
12397
12398        if (dumpAll || dumpPackage != null) {
12399            synchronized (mPidsSelfLocked) {
12400                boolean printed = false;
12401                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12402                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12403                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12404                        continue;
12405                    }
12406                    if (!printed) {
12407                        if (needSep) pw.println();
12408                        needSep = true;
12409                        pw.println("  PID mappings:");
12410                        printed = true;
12411                        printedAnything = true;
12412                    }
12413                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12414                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12415                }
12416            }
12417        }
12418
12419        if (mForegroundProcesses.size() > 0) {
12420            synchronized (mPidsSelfLocked) {
12421                boolean printed = false;
12422                for (int i=0; i<mForegroundProcesses.size(); i++) {
12423                    ProcessRecord r = mPidsSelfLocked.get(
12424                            mForegroundProcesses.valueAt(i).pid);
12425                    if (dumpPackage != null && (r == null
12426                            || !r.pkgList.containsKey(dumpPackage))) {
12427                        continue;
12428                    }
12429                    if (!printed) {
12430                        if (needSep) pw.println();
12431                        needSep = true;
12432                        pw.println("  Foreground Processes:");
12433                        printed = true;
12434                        printedAnything = true;
12435                    }
12436                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12437                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12438                }
12439            }
12440        }
12441
12442        if (mPersistentStartingProcesses.size() > 0) {
12443            if (needSep) pw.println();
12444            needSep = true;
12445            printedAnything = true;
12446            pw.println("  Persisent processes that are starting:");
12447            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12448                    "Starting Norm", "Restarting PERS", dumpPackage);
12449        }
12450
12451        if (mRemovedProcesses.size() > 0) {
12452            if (needSep) pw.println();
12453            needSep = true;
12454            printedAnything = true;
12455            pw.println("  Processes that are being removed:");
12456            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12457                    "Removed Norm", "Removed PERS", dumpPackage);
12458        }
12459
12460        if (mProcessesOnHold.size() > 0) {
12461            if (needSep) pw.println();
12462            needSep = true;
12463            printedAnything = true;
12464            pw.println("  Processes that are on old until the system is ready:");
12465            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12466                    "OnHold Norm", "OnHold PERS", dumpPackage);
12467        }
12468
12469        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12470
12471        if (mProcessCrashTimes.getMap().size() > 0) {
12472            boolean printed = false;
12473            long now = SystemClock.uptimeMillis();
12474            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12475            final int NP = pmap.size();
12476            for (int ip=0; ip<NP; ip++) {
12477                String pname = pmap.keyAt(ip);
12478                SparseArray<Long> uids = pmap.valueAt(ip);
12479                final int N = uids.size();
12480                for (int i=0; i<N; i++) {
12481                    int puid = uids.keyAt(i);
12482                    ProcessRecord r = mProcessNames.get(pname, puid);
12483                    if (dumpPackage != null && (r == null
12484                            || !r.pkgList.containsKey(dumpPackage))) {
12485                        continue;
12486                    }
12487                    if (!printed) {
12488                        if (needSep) pw.println();
12489                        needSep = true;
12490                        pw.println("  Time since processes crashed:");
12491                        printed = true;
12492                        printedAnything = true;
12493                    }
12494                    pw.print("    Process "); pw.print(pname);
12495                            pw.print(" uid "); pw.print(puid);
12496                            pw.print(": last crashed ");
12497                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12498                            pw.println(" ago");
12499                }
12500            }
12501        }
12502
12503        if (mBadProcesses.getMap().size() > 0) {
12504            boolean printed = false;
12505            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12506            final int NP = pmap.size();
12507            for (int ip=0; ip<NP; ip++) {
12508                String pname = pmap.keyAt(ip);
12509                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12510                final int N = uids.size();
12511                for (int i=0; i<N; i++) {
12512                    int puid = uids.keyAt(i);
12513                    ProcessRecord r = mProcessNames.get(pname, puid);
12514                    if (dumpPackage != null && (r == null
12515                            || !r.pkgList.containsKey(dumpPackage))) {
12516                        continue;
12517                    }
12518                    if (!printed) {
12519                        if (needSep) pw.println();
12520                        needSep = true;
12521                        pw.println("  Bad processes:");
12522                        printedAnything = true;
12523                    }
12524                    BadProcessInfo info = uids.valueAt(i);
12525                    pw.print("    Bad process "); pw.print(pname);
12526                            pw.print(" uid "); pw.print(puid);
12527                            pw.print(": crashed at time "); pw.println(info.time);
12528                    if (info.shortMsg != null) {
12529                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12530                    }
12531                    if (info.longMsg != null) {
12532                        pw.print("      Long msg: "); pw.println(info.longMsg);
12533                    }
12534                    if (info.stack != null) {
12535                        pw.println("      Stack:");
12536                        int lastPos = 0;
12537                        for (int pos=0; pos<info.stack.length(); pos++) {
12538                            if (info.stack.charAt(pos) == '\n') {
12539                                pw.print("        ");
12540                                pw.write(info.stack, lastPos, pos-lastPos);
12541                                pw.println();
12542                                lastPos = pos+1;
12543                            }
12544                        }
12545                        if (lastPos < info.stack.length()) {
12546                            pw.print("        ");
12547                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12548                            pw.println();
12549                        }
12550                    }
12551                }
12552            }
12553        }
12554
12555        if (dumpPackage == null) {
12556            pw.println();
12557            needSep = false;
12558            pw.println("  mStartedUsers:");
12559            for (int i=0; i<mStartedUsers.size(); i++) {
12560                UserStartedState uss = mStartedUsers.valueAt(i);
12561                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12562                        pw.print(": "); uss.dump("", pw);
12563            }
12564            pw.print("  mStartedUserArray: [");
12565            for (int i=0; i<mStartedUserArray.length; i++) {
12566                if (i > 0) pw.print(", ");
12567                pw.print(mStartedUserArray[i]);
12568            }
12569            pw.println("]");
12570            pw.print("  mUserLru: [");
12571            for (int i=0; i<mUserLru.size(); i++) {
12572                if (i > 0) pw.print(", ");
12573                pw.print(mUserLru.get(i));
12574            }
12575            pw.println("]");
12576            if (dumpAll) {
12577                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12578            }
12579            synchronized (mUserProfileGroupIdsSelfLocked) {
12580                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12581                    pw.println("  mUserProfileGroupIds:");
12582                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12583                        pw.print("    User #");
12584                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12585                        pw.print(" -> profile #");
12586                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12587                    }
12588                }
12589            }
12590        }
12591        if (mHomeProcess != null && (dumpPackage == null
12592                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12593            if (needSep) {
12594                pw.println();
12595                needSep = false;
12596            }
12597            pw.println("  mHomeProcess: " + mHomeProcess);
12598        }
12599        if (mPreviousProcess != null && (dumpPackage == null
12600                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12601            if (needSep) {
12602                pw.println();
12603                needSep = false;
12604            }
12605            pw.println("  mPreviousProcess: " + mPreviousProcess);
12606        }
12607        if (dumpAll) {
12608            StringBuilder sb = new StringBuilder(128);
12609            sb.append("  mPreviousProcessVisibleTime: ");
12610            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12611            pw.println(sb);
12612        }
12613        if (mHeavyWeightProcess != null && (dumpPackage == null
12614                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12615            if (needSep) {
12616                pw.println();
12617                needSep = false;
12618            }
12619            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12620        }
12621        if (dumpPackage == null) {
12622            pw.println("  mConfiguration: " + mConfiguration);
12623        }
12624        if (dumpAll) {
12625            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12626            if (mCompatModePackages.getPackages().size() > 0) {
12627                boolean printed = false;
12628                for (Map.Entry<String, Integer> entry
12629                        : mCompatModePackages.getPackages().entrySet()) {
12630                    String pkg = entry.getKey();
12631                    int mode = entry.getValue();
12632                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12633                        continue;
12634                    }
12635                    if (!printed) {
12636                        pw.println("  mScreenCompatPackages:");
12637                        printed = true;
12638                    }
12639                    pw.print("    "); pw.print(pkg); pw.print(": ");
12640                            pw.print(mode); pw.println();
12641                }
12642            }
12643        }
12644        if (dumpPackage == null) {
12645            if (mSleeping || mWentToSleep || mLockScreenShown) {
12646                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12647                        + " mLockScreenShown " + mLockScreenShown);
12648            }
12649            if (mShuttingDown || mRunningVoice) {
12650                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12651            }
12652        }
12653        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12654                || mOrigWaitForDebugger) {
12655            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12656                    || dumpPackage.equals(mOrigDebugApp)) {
12657                if (needSep) {
12658                    pw.println();
12659                    needSep = false;
12660                }
12661                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12662                        + " mDebugTransient=" + mDebugTransient
12663                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12664            }
12665        }
12666        if (mOpenGlTraceApp != null) {
12667            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12668                if (needSep) {
12669                    pw.println();
12670                    needSep = false;
12671                }
12672                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12673            }
12674        }
12675        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12676                || mProfileFd != null) {
12677            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12678                if (needSep) {
12679                    pw.println();
12680                    needSep = false;
12681                }
12682                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12683                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12684                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12685                        + mAutoStopProfiler);
12686                pw.println("  mProfileType=" + mProfileType);
12687            }
12688        }
12689        if (dumpPackage == null) {
12690            if (mAlwaysFinishActivities || mController != null) {
12691                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12692                        + " mController=" + mController);
12693            }
12694            if (dumpAll) {
12695                pw.println("  Total persistent processes: " + numPers);
12696                pw.println("  mProcessesReady=" + mProcessesReady
12697                        + " mSystemReady=" + mSystemReady);
12698                pw.println("  mBooting=" + mBooting
12699                        + " mBooted=" + mBooted
12700                        + " mFactoryTest=" + mFactoryTest);
12701                pw.print("  mLastPowerCheckRealtime=");
12702                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12703                        pw.println("");
12704                pw.print("  mLastPowerCheckUptime=");
12705                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12706                        pw.println("");
12707                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12708                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12709                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12710                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12711                        + " (" + mLruProcesses.size() + " total)"
12712                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12713                        + " mNumServiceProcs=" + mNumServiceProcs
12714                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12715                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12716                        + " mLastMemoryLevel" + mLastMemoryLevel
12717                        + " mLastNumProcesses" + mLastNumProcesses);
12718                long now = SystemClock.uptimeMillis();
12719                pw.print("  mLastIdleTime=");
12720                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12721                        pw.print(" mLowRamSinceLastIdle=");
12722                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12723                        pw.println();
12724            }
12725        }
12726
12727        if (!printedAnything) {
12728            pw.println("  (nothing)");
12729        }
12730    }
12731
12732    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12733            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12734        if (mProcessesToGc.size() > 0) {
12735            boolean printed = false;
12736            long now = SystemClock.uptimeMillis();
12737            for (int i=0; i<mProcessesToGc.size(); i++) {
12738                ProcessRecord proc = mProcessesToGc.get(i);
12739                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12740                    continue;
12741                }
12742                if (!printed) {
12743                    if (needSep) pw.println();
12744                    needSep = true;
12745                    pw.println("  Processes that are waiting to GC:");
12746                    printed = true;
12747                }
12748                pw.print("    Process "); pw.println(proc);
12749                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12750                        pw.print(", last gced=");
12751                        pw.print(now-proc.lastRequestedGc);
12752                        pw.print(" ms ago, last lowMem=");
12753                        pw.print(now-proc.lastLowMemory);
12754                        pw.println(" ms ago");
12755
12756            }
12757        }
12758        return needSep;
12759    }
12760
12761    void printOomLevel(PrintWriter pw, String name, int adj) {
12762        pw.print("    ");
12763        if (adj >= 0) {
12764            pw.print(' ');
12765            if (adj < 10) pw.print(' ');
12766        } else {
12767            if (adj > -10) pw.print(' ');
12768        }
12769        pw.print(adj);
12770        pw.print(": ");
12771        pw.print(name);
12772        pw.print(" (");
12773        pw.print(mProcessList.getMemLevel(adj)/1024);
12774        pw.println(" kB)");
12775    }
12776
12777    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12778            int opti, boolean dumpAll) {
12779        boolean needSep = false;
12780
12781        if (mLruProcesses.size() > 0) {
12782            if (needSep) pw.println();
12783            needSep = true;
12784            pw.println("  OOM levels:");
12785            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12786            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12787            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12788            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12789            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12790            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12791            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12792            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12793            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12794            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12795            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12796            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12797            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12798
12799            if (needSep) pw.println();
12800            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12801                    pw.print(" total, non-act at ");
12802                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12803                    pw.print(", non-svc at ");
12804                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12805                    pw.println("):");
12806            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12807            needSep = true;
12808        }
12809
12810        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12811
12812        pw.println();
12813        pw.println("  mHomeProcess: " + mHomeProcess);
12814        pw.println("  mPreviousProcess: " + mPreviousProcess);
12815        if (mHeavyWeightProcess != null) {
12816            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12817        }
12818
12819        return true;
12820    }
12821
12822    /**
12823     * There are three ways to call this:
12824     *  - no provider specified: dump all the providers
12825     *  - a flattened component name that matched an existing provider was specified as the
12826     *    first arg: dump that one provider
12827     *  - the first arg isn't the flattened component name of an existing provider:
12828     *    dump all providers whose component contains the first arg as a substring
12829     */
12830    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12831            int opti, boolean dumpAll) {
12832        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12833    }
12834
12835    static class ItemMatcher {
12836        ArrayList<ComponentName> components;
12837        ArrayList<String> strings;
12838        ArrayList<Integer> objects;
12839        boolean all;
12840
12841        ItemMatcher() {
12842            all = true;
12843        }
12844
12845        void build(String name) {
12846            ComponentName componentName = ComponentName.unflattenFromString(name);
12847            if (componentName != null) {
12848                if (components == null) {
12849                    components = new ArrayList<ComponentName>();
12850                }
12851                components.add(componentName);
12852                all = false;
12853            } else {
12854                int objectId = 0;
12855                // Not a '/' separated full component name; maybe an object ID?
12856                try {
12857                    objectId = Integer.parseInt(name, 16);
12858                    if (objects == null) {
12859                        objects = new ArrayList<Integer>();
12860                    }
12861                    objects.add(objectId);
12862                    all = false;
12863                } catch (RuntimeException e) {
12864                    // Not an integer; just do string match.
12865                    if (strings == null) {
12866                        strings = new ArrayList<String>();
12867                    }
12868                    strings.add(name);
12869                    all = false;
12870                }
12871            }
12872        }
12873
12874        int build(String[] args, int opti) {
12875            for (; opti<args.length; opti++) {
12876                String name = args[opti];
12877                if ("--".equals(name)) {
12878                    return opti+1;
12879                }
12880                build(name);
12881            }
12882            return opti;
12883        }
12884
12885        boolean match(Object object, ComponentName comp) {
12886            if (all) {
12887                return true;
12888            }
12889            if (components != null) {
12890                for (int i=0; i<components.size(); i++) {
12891                    if (components.get(i).equals(comp)) {
12892                        return true;
12893                    }
12894                }
12895            }
12896            if (objects != null) {
12897                for (int i=0; i<objects.size(); i++) {
12898                    if (System.identityHashCode(object) == objects.get(i)) {
12899                        return true;
12900                    }
12901                }
12902            }
12903            if (strings != null) {
12904                String flat = comp.flattenToString();
12905                for (int i=0; i<strings.size(); i++) {
12906                    if (flat.contains(strings.get(i))) {
12907                        return true;
12908                    }
12909                }
12910            }
12911            return false;
12912        }
12913    }
12914
12915    /**
12916     * There are three things that cmd can be:
12917     *  - a flattened component name that matches an existing activity
12918     *  - the cmd arg isn't the flattened component name of an existing activity:
12919     *    dump all activity whose component contains the cmd as a substring
12920     *  - A hex number of the ActivityRecord object instance.
12921     */
12922    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12923            int opti, boolean dumpAll) {
12924        ArrayList<ActivityRecord> activities;
12925
12926        synchronized (this) {
12927            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12928        }
12929
12930        if (activities.size() <= 0) {
12931            return false;
12932        }
12933
12934        String[] newArgs = new String[args.length - opti];
12935        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12936
12937        TaskRecord lastTask = null;
12938        boolean needSep = false;
12939        for (int i=activities.size()-1; i>=0; i--) {
12940            ActivityRecord r = activities.get(i);
12941            if (needSep) {
12942                pw.println();
12943            }
12944            needSep = true;
12945            synchronized (this) {
12946                if (lastTask != r.task) {
12947                    lastTask = r.task;
12948                    pw.print("TASK "); pw.print(lastTask.affinity);
12949                            pw.print(" id="); pw.println(lastTask.taskId);
12950                    if (dumpAll) {
12951                        lastTask.dump(pw, "  ");
12952                    }
12953                }
12954            }
12955            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12956        }
12957        return true;
12958    }
12959
12960    /**
12961     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12962     * there is a thread associated with the activity.
12963     */
12964    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12965            final ActivityRecord r, String[] args, boolean dumpAll) {
12966        String innerPrefix = prefix + "  ";
12967        synchronized (this) {
12968            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12969                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12970                    pw.print(" pid=");
12971                    if (r.app != null) pw.println(r.app.pid);
12972                    else pw.println("(not running)");
12973            if (dumpAll) {
12974                r.dump(pw, innerPrefix);
12975            }
12976        }
12977        if (r.app != null && r.app.thread != null) {
12978            // flush anything that is already in the PrintWriter since the thread is going
12979            // to write to the file descriptor directly
12980            pw.flush();
12981            try {
12982                TransferPipe tp = new TransferPipe();
12983                try {
12984                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12985                            r.appToken, innerPrefix, args);
12986                    tp.go(fd);
12987                } finally {
12988                    tp.kill();
12989                }
12990            } catch (IOException e) {
12991                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12992            } catch (RemoteException e) {
12993                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12994            }
12995        }
12996    }
12997
12998    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12999            int opti, boolean dumpAll, String dumpPackage) {
13000        boolean needSep = false;
13001        boolean onlyHistory = false;
13002        boolean printedAnything = false;
13003
13004        if ("history".equals(dumpPackage)) {
13005            if (opti < args.length && "-s".equals(args[opti])) {
13006                dumpAll = false;
13007            }
13008            onlyHistory = true;
13009            dumpPackage = null;
13010        }
13011
13012        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13013        if (!onlyHistory && dumpAll) {
13014            if (mRegisteredReceivers.size() > 0) {
13015                boolean printed = false;
13016                Iterator it = mRegisteredReceivers.values().iterator();
13017                while (it.hasNext()) {
13018                    ReceiverList r = (ReceiverList)it.next();
13019                    if (dumpPackage != null && (r.app == null ||
13020                            !dumpPackage.equals(r.app.info.packageName))) {
13021                        continue;
13022                    }
13023                    if (!printed) {
13024                        pw.println("  Registered Receivers:");
13025                        needSep = true;
13026                        printed = true;
13027                        printedAnything = true;
13028                    }
13029                    pw.print("  * "); pw.println(r);
13030                    r.dump(pw, "    ");
13031                }
13032            }
13033
13034            if (mReceiverResolver.dump(pw, needSep ?
13035                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13036                    "    ", dumpPackage, false)) {
13037                needSep = true;
13038                printedAnything = true;
13039            }
13040        }
13041
13042        for (BroadcastQueue q : mBroadcastQueues) {
13043            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13044            printedAnything |= needSep;
13045        }
13046
13047        needSep = true;
13048
13049        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13050            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13051                if (needSep) {
13052                    pw.println();
13053                }
13054                needSep = true;
13055                printedAnything = true;
13056                pw.print("  Sticky broadcasts for user ");
13057                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13058                StringBuilder sb = new StringBuilder(128);
13059                for (Map.Entry<String, ArrayList<Intent>> ent
13060                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13061                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13062                    if (dumpAll) {
13063                        pw.println(":");
13064                        ArrayList<Intent> intents = ent.getValue();
13065                        final int N = intents.size();
13066                        for (int i=0; i<N; i++) {
13067                            sb.setLength(0);
13068                            sb.append("    Intent: ");
13069                            intents.get(i).toShortString(sb, false, true, false, false);
13070                            pw.println(sb.toString());
13071                            Bundle bundle = intents.get(i).getExtras();
13072                            if (bundle != null) {
13073                                pw.print("      ");
13074                                pw.println(bundle.toString());
13075                            }
13076                        }
13077                    } else {
13078                        pw.println("");
13079                    }
13080                }
13081            }
13082        }
13083
13084        if (!onlyHistory && dumpAll) {
13085            pw.println();
13086            for (BroadcastQueue queue : mBroadcastQueues) {
13087                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13088                        + queue.mBroadcastsScheduled);
13089            }
13090            pw.println("  mHandler:");
13091            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13092            needSep = true;
13093            printedAnything = true;
13094        }
13095
13096        if (!printedAnything) {
13097            pw.println("  (nothing)");
13098        }
13099    }
13100
13101    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13102            int opti, boolean dumpAll, String dumpPackage) {
13103        boolean needSep;
13104        boolean printedAnything = false;
13105
13106        ItemMatcher matcher = new ItemMatcher();
13107        matcher.build(args, opti);
13108
13109        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13110
13111        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13112        printedAnything |= needSep;
13113
13114        if (mLaunchingProviders.size() > 0) {
13115            boolean printed = false;
13116            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13117                ContentProviderRecord r = mLaunchingProviders.get(i);
13118                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13119                    continue;
13120                }
13121                if (!printed) {
13122                    if (needSep) pw.println();
13123                    needSep = true;
13124                    pw.println("  Launching content providers:");
13125                    printed = true;
13126                    printedAnything = true;
13127                }
13128                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13129                        pw.println(r);
13130            }
13131        }
13132
13133        if (mGrantedUriPermissions.size() > 0) {
13134            boolean printed = false;
13135            int dumpUid = -2;
13136            if (dumpPackage != null) {
13137                try {
13138                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13139                } catch (NameNotFoundException e) {
13140                    dumpUid = -1;
13141                }
13142            }
13143            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13144                int uid = mGrantedUriPermissions.keyAt(i);
13145                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13146                    continue;
13147                }
13148                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13149                if (!printed) {
13150                    if (needSep) pw.println();
13151                    needSep = true;
13152                    pw.println("  Granted Uri Permissions:");
13153                    printed = true;
13154                    printedAnything = true;
13155                }
13156                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13157                for (UriPermission perm : perms.values()) {
13158                    pw.print("    "); pw.println(perm);
13159                    if (dumpAll) {
13160                        perm.dump(pw, "      ");
13161                    }
13162                }
13163            }
13164        }
13165
13166        if (!printedAnything) {
13167            pw.println("  (nothing)");
13168        }
13169    }
13170
13171    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13172            int opti, boolean dumpAll, String dumpPackage) {
13173        boolean printed = false;
13174
13175        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13176
13177        if (mIntentSenderRecords.size() > 0) {
13178            Iterator<WeakReference<PendingIntentRecord>> it
13179                    = mIntentSenderRecords.values().iterator();
13180            while (it.hasNext()) {
13181                WeakReference<PendingIntentRecord> ref = it.next();
13182                PendingIntentRecord rec = ref != null ? ref.get(): null;
13183                if (dumpPackage != null && (rec == null
13184                        || !dumpPackage.equals(rec.key.packageName))) {
13185                    continue;
13186                }
13187                printed = true;
13188                if (rec != null) {
13189                    pw.print("  * "); pw.println(rec);
13190                    if (dumpAll) {
13191                        rec.dump(pw, "    ");
13192                    }
13193                } else {
13194                    pw.print("  * "); pw.println(ref);
13195                }
13196            }
13197        }
13198
13199        if (!printed) {
13200            pw.println("  (nothing)");
13201        }
13202    }
13203
13204    private static final int dumpProcessList(PrintWriter pw,
13205            ActivityManagerService service, List list,
13206            String prefix, String normalLabel, String persistentLabel,
13207            String dumpPackage) {
13208        int numPers = 0;
13209        final int N = list.size()-1;
13210        for (int i=N; i>=0; i--) {
13211            ProcessRecord r = (ProcessRecord)list.get(i);
13212            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13213                continue;
13214            }
13215            pw.println(String.format("%s%s #%2d: %s",
13216                    prefix, (r.persistent ? persistentLabel : normalLabel),
13217                    i, r.toString()));
13218            if (r.persistent) {
13219                numPers++;
13220            }
13221        }
13222        return numPers;
13223    }
13224
13225    private static final boolean dumpProcessOomList(PrintWriter pw,
13226            ActivityManagerService service, List<ProcessRecord> origList,
13227            String prefix, String normalLabel, String persistentLabel,
13228            boolean inclDetails, String dumpPackage) {
13229
13230        ArrayList<Pair<ProcessRecord, Integer>> list
13231                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13232        for (int i=0; i<origList.size(); i++) {
13233            ProcessRecord r = origList.get(i);
13234            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13235                continue;
13236            }
13237            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13238        }
13239
13240        if (list.size() <= 0) {
13241            return false;
13242        }
13243
13244        Comparator<Pair<ProcessRecord, Integer>> comparator
13245                = new Comparator<Pair<ProcessRecord, Integer>>() {
13246            @Override
13247            public int compare(Pair<ProcessRecord, Integer> object1,
13248                    Pair<ProcessRecord, Integer> object2) {
13249                if (object1.first.setAdj != object2.first.setAdj) {
13250                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13251                }
13252                if (object1.second.intValue() != object2.second.intValue()) {
13253                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13254                }
13255                return 0;
13256            }
13257        };
13258
13259        Collections.sort(list, comparator);
13260
13261        final long curRealtime = SystemClock.elapsedRealtime();
13262        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13263        final long curUptime = SystemClock.uptimeMillis();
13264        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13265
13266        for (int i=list.size()-1; i>=0; i--) {
13267            ProcessRecord r = list.get(i).first;
13268            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13269            char schedGroup;
13270            switch (r.setSchedGroup) {
13271                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13272                    schedGroup = 'B';
13273                    break;
13274                case Process.THREAD_GROUP_DEFAULT:
13275                    schedGroup = 'F';
13276                    break;
13277                default:
13278                    schedGroup = '?';
13279                    break;
13280            }
13281            char foreground;
13282            if (r.foregroundActivities) {
13283                foreground = 'A';
13284            } else if (r.foregroundServices) {
13285                foreground = 'S';
13286            } else {
13287                foreground = ' ';
13288            }
13289            String procState = ProcessList.makeProcStateString(r.curProcState);
13290            pw.print(prefix);
13291            pw.print(r.persistent ? persistentLabel : normalLabel);
13292            pw.print(" #");
13293            int num = (origList.size()-1)-list.get(i).second;
13294            if (num < 10) pw.print(' ');
13295            pw.print(num);
13296            pw.print(": ");
13297            pw.print(oomAdj);
13298            pw.print(' ');
13299            pw.print(schedGroup);
13300            pw.print('/');
13301            pw.print(foreground);
13302            pw.print('/');
13303            pw.print(procState);
13304            pw.print(" trm:");
13305            if (r.trimMemoryLevel < 10) pw.print(' ');
13306            pw.print(r.trimMemoryLevel);
13307            pw.print(' ');
13308            pw.print(r.toShortString());
13309            pw.print(" (");
13310            pw.print(r.adjType);
13311            pw.println(')');
13312            if (r.adjSource != null || r.adjTarget != null) {
13313                pw.print(prefix);
13314                pw.print("    ");
13315                if (r.adjTarget instanceof ComponentName) {
13316                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13317                } else if (r.adjTarget != null) {
13318                    pw.print(r.adjTarget.toString());
13319                } else {
13320                    pw.print("{null}");
13321                }
13322                pw.print("<=");
13323                if (r.adjSource instanceof ProcessRecord) {
13324                    pw.print("Proc{");
13325                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13326                    pw.println("}");
13327                } else if (r.adjSource != null) {
13328                    pw.println(r.adjSource.toString());
13329                } else {
13330                    pw.println("{null}");
13331                }
13332            }
13333            if (inclDetails) {
13334                pw.print(prefix);
13335                pw.print("    ");
13336                pw.print("oom: max="); pw.print(r.maxAdj);
13337                pw.print(" curRaw="); pw.print(r.curRawAdj);
13338                pw.print(" setRaw="); pw.print(r.setRawAdj);
13339                pw.print(" cur="); pw.print(r.curAdj);
13340                pw.print(" set="); pw.println(r.setAdj);
13341                pw.print(prefix);
13342                pw.print("    ");
13343                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13344                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13345                pw.print(" lastPss="); pw.print(r.lastPss);
13346                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13347                pw.print(prefix);
13348                pw.print("    ");
13349                pw.print("cached="); pw.print(r.cached);
13350                pw.print(" empty="); pw.print(r.empty);
13351                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13352
13353                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13354                    if (r.lastWakeTime != 0) {
13355                        long wtime;
13356                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13357                        synchronized (stats) {
13358                            wtime = stats.getProcessWakeTime(r.info.uid,
13359                                    r.pid, curRealtime);
13360                        }
13361                        long timeUsed = wtime - r.lastWakeTime;
13362                        pw.print(prefix);
13363                        pw.print("    ");
13364                        pw.print("keep awake over ");
13365                        TimeUtils.formatDuration(realtimeSince, pw);
13366                        pw.print(" used ");
13367                        TimeUtils.formatDuration(timeUsed, pw);
13368                        pw.print(" (");
13369                        pw.print((timeUsed*100)/realtimeSince);
13370                        pw.println("%)");
13371                    }
13372                    if (r.lastCpuTime != 0) {
13373                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13374                        pw.print(prefix);
13375                        pw.print("    ");
13376                        pw.print("run cpu over ");
13377                        TimeUtils.formatDuration(uptimeSince, pw);
13378                        pw.print(" used ");
13379                        TimeUtils.formatDuration(timeUsed, pw);
13380                        pw.print(" (");
13381                        pw.print((timeUsed*100)/uptimeSince);
13382                        pw.println("%)");
13383                    }
13384                }
13385            }
13386        }
13387        return true;
13388    }
13389
13390    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13391        ArrayList<ProcessRecord> procs;
13392        synchronized (this) {
13393            if (args != null && args.length > start
13394                    && args[start].charAt(0) != '-') {
13395                procs = new ArrayList<ProcessRecord>();
13396                int pid = -1;
13397                try {
13398                    pid = Integer.parseInt(args[start]);
13399                } catch (NumberFormatException e) {
13400                }
13401                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13402                    ProcessRecord proc = mLruProcesses.get(i);
13403                    if (proc.pid == pid) {
13404                        procs.add(proc);
13405                    } else if (proc.processName.equals(args[start])) {
13406                        procs.add(proc);
13407                    }
13408                }
13409                if (procs.size() <= 0) {
13410                    return null;
13411                }
13412            } else {
13413                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13414            }
13415        }
13416        return procs;
13417    }
13418
13419    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13420            PrintWriter pw, String[] args) {
13421        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13422        if (procs == null) {
13423            pw.println("No process found for: " + args[0]);
13424            return;
13425        }
13426
13427        long uptime = SystemClock.uptimeMillis();
13428        long realtime = SystemClock.elapsedRealtime();
13429        pw.println("Applications Graphics Acceleration Info:");
13430        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13431
13432        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13433            ProcessRecord r = procs.get(i);
13434            if (r.thread != null) {
13435                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13436                pw.flush();
13437                try {
13438                    TransferPipe tp = new TransferPipe();
13439                    try {
13440                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13441                        tp.go(fd);
13442                    } finally {
13443                        tp.kill();
13444                    }
13445                } catch (IOException e) {
13446                    pw.println("Failure while dumping the app: " + r);
13447                    pw.flush();
13448                } catch (RemoteException e) {
13449                    pw.println("Got a RemoteException while dumping the app " + r);
13450                    pw.flush();
13451                }
13452            }
13453        }
13454    }
13455
13456    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13457        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13458        if (procs == null) {
13459            pw.println("No process found for: " + args[0]);
13460            return;
13461        }
13462
13463        pw.println("Applications Database Info:");
13464
13465        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13466            ProcessRecord r = procs.get(i);
13467            if (r.thread != null) {
13468                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13469                pw.flush();
13470                try {
13471                    TransferPipe tp = new TransferPipe();
13472                    try {
13473                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13474                        tp.go(fd);
13475                    } finally {
13476                        tp.kill();
13477                    }
13478                } catch (IOException e) {
13479                    pw.println("Failure while dumping the app: " + r);
13480                    pw.flush();
13481                } catch (RemoteException e) {
13482                    pw.println("Got a RemoteException while dumping the app " + r);
13483                    pw.flush();
13484                }
13485            }
13486        }
13487    }
13488
13489    final static class MemItem {
13490        final boolean isProc;
13491        final String label;
13492        final String shortLabel;
13493        final long pss;
13494        final int id;
13495        final boolean hasActivities;
13496        ArrayList<MemItem> subitems;
13497
13498        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13499                boolean _hasActivities) {
13500            isProc = true;
13501            label = _label;
13502            shortLabel = _shortLabel;
13503            pss = _pss;
13504            id = _id;
13505            hasActivities = _hasActivities;
13506        }
13507
13508        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13509            isProc = false;
13510            label = _label;
13511            shortLabel = _shortLabel;
13512            pss = _pss;
13513            id = _id;
13514            hasActivities = false;
13515        }
13516    }
13517
13518    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13519            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13520        if (sort && !isCompact) {
13521            Collections.sort(items, new Comparator<MemItem>() {
13522                @Override
13523                public int compare(MemItem lhs, MemItem rhs) {
13524                    if (lhs.pss < rhs.pss) {
13525                        return 1;
13526                    } else if (lhs.pss > rhs.pss) {
13527                        return -1;
13528                    }
13529                    return 0;
13530                }
13531            });
13532        }
13533
13534        for (int i=0; i<items.size(); i++) {
13535            MemItem mi = items.get(i);
13536            if (!isCompact) {
13537                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13538            } else if (mi.isProc) {
13539                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13540                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13541                pw.println(mi.hasActivities ? ",a" : ",e");
13542            } else {
13543                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13544                pw.println(mi.pss);
13545            }
13546            if (mi.subitems != null) {
13547                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13548                        true, isCompact);
13549            }
13550        }
13551    }
13552
13553    // These are in KB.
13554    static final long[] DUMP_MEM_BUCKETS = new long[] {
13555        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13556        120*1024, 160*1024, 200*1024,
13557        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13558        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13559    };
13560
13561    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13562            boolean stackLike) {
13563        int start = label.lastIndexOf('.');
13564        if (start >= 0) start++;
13565        else start = 0;
13566        int end = label.length();
13567        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13568            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13569                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13570                out.append(bucket);
13571                out.append(stackLike ? "MB." : "MB ");
13572                out.append(label, start, end);
13573                return;
13574            }
13575        }
13576        out.append(memKB/1024);
13577        out.append(stackLike ? "MB." : "MB ");
13578        out.append(label, start, end);
13579    }
13580
13581    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13582            ProcessList.NATIVE_ADJ,
13583            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13584            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13585            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13586            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13587            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13588    };
13589    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13590            "Native",
13591            "System", "Persistent", "Foreground",
13592            "Visible", "Perceptible",
13593            "Heavy Weight", "Backup",
13594            "A Services", "Home",
13595            "Previous", "B Services", "Cached"
13596    };
13597    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13598            "native",
13599            "sys", "pers", "fore",
13600            "vis", "percept",
13601            "heavy", "backup",
13602            "servicea", "home",
13603            "prev", "serviceb", "cached"
13604    };
13605
13606    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13607            long realtime, boolean isCheckinRequest, boolean isCompact) {
13608        if (isCheckinRequest || isCompact) {
13609            // short checkin version
13610            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13611        } else {
13612            pw.println("Applications Memory Usage (kB):");
13613            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13614        }
13615    }
13616
13617    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13618            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13619        boolean dumpDetails = false;
13620        boolean dumpFullDetails = false;
13621        boolean dumpDalvik = false;
13622        boolean oomOnly = false;
13623        boolean isCompact = false;
13624        boolean localOnly = false;
13625
13626        int opti = 0;
13627        while (opti < args.length) {
13628            String opt = args[opti];
13629            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13630                break;
13631            }
13632            opti++;
13633            if ("-a".equals(opt)) {
13634                dumpDetails = true;
13635                dumpFullDetails = true;
13636                dumpDalvik = true;
13637            } else if ("-d".equals(opt)) {
13638                dumpDalvik = true;
13639            } else if ("-c".equals(opt)) {
13640                isCompact = true;
13641            } else if ("--oom".equals(opt)) {
13642                oomOnly = true;
13643            } else if ("--local".equals(opt)) {
13644                localOnly = true;
13645            } else if ("-h".equals(opt)) {
13646                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13647                pw.println("  -a: include all available information for each process.");
13648                pw.println("  -d: include dalvik details when dumping process details.");
13649                pw.println("  -c: dump in a compact machine-parseable representation.");
13650                pw.println("  --oom: only show processes organized by oom adj.");
13651                pw.println("  --local: only collect details locally, don't call process.");
13652                pw.println("If [process] is specified it can be the name or ");
13653                pw.println("pid of a specific process to dump.");
13654                return;
13655            } else {
13656                pw.println("Unknown argument: " + opt + "; use -h for help");
13657            }
13658        }
13659
13660        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13661        long uptime = SystemClock.uptimeMillis();
13662        long realtime = SystemClock.elapsedRealtime();
13663        final long[] tmpLong = new long[1];
13664
13665        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13666        if (procs == null) {
13667            // No Java processes.  Maybe they want to print a native process.
13668            if (args != null && args.length > opti
13669                    && args[opti].charAt(0) != '-') {
13670                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13671                        = new ArrayList<ProcessCpuTracker.Stats>();
13672                updateCpuStatsNow();
13673                int findPid = -1;
13674                try {
13675                    findPid = Integer.parseInt(args[opti]);
13676                } catch (NumberFormatException e) {
13677                }
13678                synchronized (mProcessCpuThread) {
13679                    final int N = mProcessCpuTracker.countStats();
13680                    for (int i=0; i<N; i++) {
13681                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13682                        if (st.pid == findPid || (st.baseName != null
13683                                && st.baseName.equals(args[opti]))) {
13684                            nativeProcs.add(st);
13685                        }
13686                    }
13687                }
13688                if (nativeProcs.size() > 0) {
13689                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13690                            isCompact);
13691                    Debug.MemoryInfo mi = null;
13692                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13693                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13694                        final int pid = r.pid;
13695                        if (!isCheckinRequest && dumpDetails) {
13696                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13697                        }
13698                        if (mi == null) {
13699                            mi = new Debug.MemoryInfo();
13700                        }
13701                        if (dumpDetails || (!brief && !oomOnly)) {
13702                            Debug.getMemoryInfo(pid, mi);
13703                        } else {
13704                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13705                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13706                        }
13707                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13708                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13709                        if (isCheckinRequest) {
13710                            pw.println();
13711                        }
13712                    }
13713                    return;
13714                }
13715            }
13716            pw.println("No process found for: " + args[opti]);
13717            return;
13718        }
13719
13720        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13721            dumpDetails = true;
13722        }
13723
13724        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13725
13726        String[] innerArgs = new String[args.length-opti];
13727        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13728
13729        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13730        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13731        long nativePss=0, dalvikPss=0, otherPss=0;
13732        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13733
13734        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13735        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13736                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13737
13738        long totalPss = 0;
13739        long cachedPss = 0;
13740
13741        Debug.MemoryInfo mi = null;
13742        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13743            final ProcessRecord r = procs.get(i);
13744            final IApplicationThread thread;
13745            final int pid;
13746            final int oomAdj;
13747            final boolean hasActivities;
13748            synchronized (this) {
13749                thread = r.thread;
13750                pid = r.pid;
13751                oomAdj = r.getSetAdjWithServices();
13752                hasActivities = r.activities.size() > 0;
13753            }
13754            if (thread != null) {
13755                if (!isCheckinRequest && dumpDetails) {
13756                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13757                }
13758                if (mi == null) {
13759                    mi = new Debug.MemoryInfo();
13760                }
13761                if (dumpDetails || (!brief && !oomOnly)) {
13762                    Debug.getMemoryInfo(pid, mi);
13763                } else {
13764                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13765                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13766                }
13767                if (dumpDetails) {
13768                    if (localOnly) {
13769                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13770                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13771                        if (isCheckinRequest) {
13772                            pw.println();
13773                        }
13774                    } else {
13775                        try {
13776                            pw.flush();
13777                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13778                                    dumpDalvik, innerArgs);
13779                        } catch (RemoteException e) {
13780                            if (!isCheckinRequest) {
13781                                pw.println("Got RemoteException!");
13782                                pw.flush();
13783                            }
13784                        }
13785                    }
13786                }
13787
13788                final long myTotalPss = mi.getTotalPss();
13789                final long myTotalUss = mi.getTotalUss();
13790
13791                synchronized (this) {
13792                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13793                        // Record this for posterity if the process has been stable.
13794                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13795                    }
13796                }
13797
13798                if (!isCheckinRequest && mi != null) {
13799                    totalPss += myTotalPss;
13800                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13801                            (hasActivities ? " / activities)" : ")"),
13802                            r.processName, myTotalPss, pid, hasActivities);
13803                    procMems.add(pssItem);
13804                    procMemsMap.put(pid, pssItem);
13805
13806                    nativePss += mi.nativePss;
13807                    dalvikPss += mi.dalvikPss;
13808                    otherPss += mi.otherPss;
13809                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13810                        long mem = mi.getOtherPss(j);
13811                        miscPss[j] += mem;
13812                        otherPss -= mem;
13813                    }
13814
13815                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13816                        cachedPss += myTotalPss;
13817                    }
13818
13819                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13820                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13821                                || oomIndex == (oomPss.length-1)) {
13822                            oomPss[oomIndex] += myTotalPss;
13823                            if (oomProcs[oomIndex] == null) {
13824                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13825                            }
13826                            oomProcs[oomIndex].add(pssItem);
13827                            break;
13828                        }
13829                    }
13830                }
13831            }
13832        }
13833
13834        long nativeProcTotalPss = 0;
13835
13836        if (!isCheckinRequest && procs.size() > 1) {
13837            // If we are showing aggregations, also look for native processes to
13838            // include so that our aggregations are more accurate.
13839            updateCpuStatsNow();
13840            synchronized (mProcessCpuThread) {
13841                final int N = mProcessCpuTracker.countStats();
13842                for (int i=0; i<N; i++) {
13843                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13844                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13845                        if (mi == null) {
13846                            mi = new Debug.MemoryInfo();
13847                        }
13848                        if (!brief && !oomOnly) {
13849                            Debug.getMemoryInfo(st.pid, mi);
13850                        } else {
13851                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13852                            mi.nativePrivateDirty = (int)tmpLong[0];
13853                        }
13854
13855                        final long myTotalPss = mi.getTotalPss();
13856                        totalPss += myTotalPss;
13857                        nativeProcTotalPss += myTotalPss;
13858
13859                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13860                                st.name, myTotalPss, st.pid, false);
13861                        procMems.add(pssItem);
13862
13863                        nativePss += mi.nativePss;
13864                        dalvikPss += mi.dalvikPss;
13865                        otherPss += mi.otherPss;
13866                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13867                            long mem = mi.getOtherPss(j);
13868                            miscPss[j] += mem;
13869                            otherPss -= mem;
13870                        }
13871                        oomPss[0] += myTotalPss;
13872                        if (oomProcs[0] == null) {
13873                            oomProcs[0] = new ArrayList<MemItem>();
13874                        }
13875                        oomProcs[0].add(pssItem);
13876                    }
13877                }
13878            }
13879
13880            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13881
13882            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13883            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13884            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13885            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13886                String label = Debug.MemoryInfo.getOtherLabel(j);
13887                catMems.add(new MemItem(label, label, miscPss[j], j));
13888            }
13889
13890            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13891            for (int j=0; j<oomPss.length; j++) {
13892                if (oomPss[j] != 0) {
13893                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13894                            : DUMP_MEM_OOM_LABEL[j];
13895                    MemItem item = new MemItem(label, label, oomPss[j],
13896                            DUMP_MEM_OOM_ADJ[j]);
13897                    item.subitems = oomProcs[j];
13898                    oomMems.add(item);
13899                }
13900            }
13901
13902            if (!brief && !oomOnly && !isCompact) {
13903                pw.println();
13904                pw.println("Total PSS by process:");
13905                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13906                pw.println();
13907            }
13908            if (!isCompact) {
13909                pw.println("Total PSS by OOM adjustment:");
13910            }
13911            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13912            if (!brief && !oomOnly) {
13913                PrintWriter out = categoryPw != null ? categoryPw : pw;
13914                if (!isCompact) {
13915                    out.println();
13916                    out.println("Total PSS by category:");
13917                }
13918                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13919            }
13920            if (!isCompact) {
13921                pw.println();
13922            }
13923            MemInfoReader memInfo = new MemInfoReader();
13924            memInfo.readMemInfo();
13925            if (nativeProcTotalPss > 0) {
13926                synchronized (this) {
13927                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13928                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13929                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13930                            nativeProcTotalPss);
13931                }
13932            }
13933            if (!brief) {
13934                if (!isCompact) {
13935                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13936                    pw.print(" kB (status ");
13937                    switch (mLastMemoryLevel) {
13938                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13939                            pw.println("normal)");
13940                            break;
13941                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13942                            pw.println("moderate)");
13943                            break;
13944                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13945                            pw.println("low)");
13946                            break;
13947                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13948                            pw.println("critical)");
13949                            break;
13950                        default:
13951                            pw.print(mLastMemoryLevel);
13952                            pw.println(")");
13953                            break;
13954                    }
13955                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13956                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13957                            pw.print(cachedPss); pw.print(" cached pss + ");
13958                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13959                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13960                } else {
13961                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13962                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13963                            + memInfo.getFreeSizeKb()); pw.print(",");
13964                    pw.println(totalPss - cachedPss);
13965                }
13966            }
13967            if (!isCompact) {
13968                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13969                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13970                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13971                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13972                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13973                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13974                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13975                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13976                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13977                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13978                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13979            }
13980            if (!brief) {
13981                if (memInfo.getZramTotalSizeKb() != 0) {
13982                    if (!isCompact) {
13983                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13984                                pw.print(" kB physical used for ");
13985                                pw.print(memInfo.getSwapTotalSizeKb()
13986                                        - memInfo.getSwapFreeSizeKb());
13987                                pw.print(" kB in swap (");
13988                                pw.print(memInfo.getSwapTotalSizeKb());
13989                                pw.println(" kB total swap)");
13990                    } else {
13991                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13992                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13993                                pw.println(memInfo.getSwapFreeSizeKb());
13994                    }
13995                }
13996                final int[] SINGLE_LONG_FORMAT = new int[] {
13997                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13998                };
13999                long[] longOut = new long[1];
14000                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14001                        SINGLE_LONG_FORMAT, null, longOut, null);
14002                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14003                longOut[0] = 0;
14004                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14005                        SINGLE_LONG_FORMAT, null, longOut, null);
14006                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14007                longOut[0] = 0;
14008                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14009                        SINGLE_LONG_FORMAT, null, longOut, null);
14010                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14011                longOut[0] = 0;
14012                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14013                        SINGLE_LONG_FORMAT, null, longOut, null);
14014                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14015                if (!isCompact) {
14016                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14017                        pw.print("      KSM: "); pw.print(sharing);
14018                                pw.print(" kB saved from shared ");
14019                                pw.print(shared); pw.println(" kB");
14020                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14021                                pw.print(voltile); pw.println(" kB volatile");
14022                    }
14023                    pw.print("   Tuning: ");
14024                    pw.print(ActivityManager.staticGetMemoryClass());
14025                    pw.print(" (large ");
14026                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14027                    pw.print("), oom ");
14028                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14029                    pw.print(" kB");
14030                    pw.print(", restore limit ");
14031                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14032                    pw.print(" kB");
14033                    if (ActivityManager.isLowRamDeviceStatic()) {
14034                        pw.print(" (low-ram)");
14035                    }
14036                    if (ActivityManager.isHighEndGfx()) {
14037                        pw.print(" (high-end-gfx)");
14038                    }
14039                    pw.println();
14040                } else {
14041                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14042                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14043                    pw.println(voltile);
14044                    pw.print("tuning,");
14045                    pw.print(ActivityManager.staticGetMemoryClass());
14046                    pw.print(',');
14047                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14048                    pw.print(',');
14049                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14050                    if (ActivityManager.isLowRamDeviceStatic()) {
14051                        pw.print(",low-ram");
14052                    }
14053                    if (ActivityManager.isHighEndGfx()) {
14054                        pw.print(",high-end-gfx");
14055                    }
14056                    pw.println();
14057                }
14058            }
14059        }
14060    }
14061
14062    /**
14063     * Searches array of arguments for the specified string
14064     * @param args array of argument strings
14065     * @param value value to search for
14066     * @return true if the value is contained in the array
14067     */
14068    private static boolean scanArgs(String[] args, String value) {
14069        if (args != null) {
14070            for (String arg : args) {
14071                if (value.equals(arg)) {
14072                    return true;
14073                }
14074            }
14075        }
14076        return false;
14077    }
14078
14079    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14080            ContentProviderRecord cpr, boolean always) {
14081        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14082
14083        if (!inLaunching || always) {
14084            synchronized (cpr) {
14085                cpr.launchingApp = null;
14086                cpr.notifyAll();
14087            }
14088            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14089            String names[] = cpr.info.authority.split(";");
14090            for (int j = 0; j < names.length; j++) {
14091                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14092            }
14093        }
14094
14095        for (int i=0; i<cpr.connections.size(); i++) {
14096            ContentProviderConnection conn = cpr.connections.get(i);
14097            if (conn.waiting) {
14098                // If this connection is waiting for the provider, then we don't
14099                // need to mess with its process unless we are always removing
14100                // or for some reason the provider is not currently launching.
14101                if (inLaunching && !always) {
14102                    continue;
14103                }
14104            }
14105            ProcessRecord capp = conn.client;
14106            conn.dead = true;
14107            if (conn.stableCount > 0) {
14108                if (!capp.persistent && capp.thread != null
14109                        && capp.pid != 0
14110                        && capp.pid != MY_PID) {
14111                    capp.kill("depends on provider "
14112                            + cpr.name.flattenToShortString()
14113                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14114                }
14115            } else if (capp.thread != null && conn.provider.provider != null) {
14116                try {
14117                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14118                } catch (RemoteException e) {
14119                }
14120                // In the protocol here, we don't expect the client to correctly
14121                // clean up this connection, we'll just remove it.
14122                cpr.connections.remove(i);
14123                conn.client.conProviders.remove(conn);
14124            }
14125        }
14126
14127        if (inLaunching && always) {
14128            mLaunchingProviders.remove(cpr);
14129        }
14130        return inLaunching;
14131    }
14132
14133    /**
14134     * Main code for cleaning up a process when it has gone away.  This is
14135     * called both as a result of the process dying, or directly when stopping
14136     * a process when running in single process mode.
14137     */
14138    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14139            boolean restarting, boolean allowRestart, int index) {
14140        if (index >= 0) {
14141            removeLruProcessLocked(app);
14142            ProcessList.remove(app.pid);
14143        }
14144
14145        mProcessesToGc.remove(app);
14146        mPendingPssProcesses.remove(app);
14147
14148        // Dismiss any open dialogs.
14149        if (app.crashDialog != null && !app.forceCrashReport) {
14150            app.crashDialog.dismiss();
14151            app.crashDialog = null;
14152        }
14153        if (app.anrDialog != null) {
14154            app.anrDialog.dismiss();
14155            app.anrDialog = null;
14156        }
14157        if (app.waitDialog != null) {
14158            app.waitDialog.dismiss();
14159            app.waitDialog = null;
14160        }
14161
14162        app.crashing = false;
14163        app.notResponding = false;
14164
14165        app.resetPackageList(mProcessStats);
14166        app.unlinkDeathRecipient();
14167        app.makeInactive(mProcessStats);
14168        app.waitingToKill = null;
14169        app.forcingToForeground = null;
14170        updateProcessForegroundLocked(app, false, false);
14171        app.foregroundActivities = false;
14172        app.hasShownUi = false;
14173        app.treatLikeActivity = false;
14174        app.hasAboveClient = false;
14175        app.hasClientActivities = false;
14176
14177        mServices.killServicesLocked(app, allowRestart);
14178
14179        boolean restart = false;
14180
14181        // Remove published content providers.
14182        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14183            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14184            final boolean always = app.bad || !allowRestart;
14185            if (removeDyingProviderLocked(app, cpr, always) || always) {
14186                // We left the provider in the launching list, need to
14187                // restart it.
14188                restart = true;
14189            }
14190
14191            cpr.provider = null;
14192            cpr.proc = null;
14193        }
14194        app.pubProviders.clear();
14195
14196        // Take care of any launching providers waiting for this process.
14197        if (checkAppInLaunchingProvidersLocked(app, false)) {
14198            restart = true;
14199        }
14200
14201        // Unregister from connected content providers.
14202        if (!app.conProviders.isEmpty()) {
14203            for (int i=0; i<app.conProviders.size(); i++) {
14204                ContentProviderConnection conn = app.conProviders.get(i);
14205                conn.provider.connections.remove(conn);
14206            }
14207            app.conProviders.clear();
14208        }
14209
14210        // At this point there may be remaining entries in mLaunchingProviders
14211        // where we were the only one waiting, so they are no longer of use.
14212        // Look for these and clean up if found.
14213        // XXX Commented out for now.  Trying to figure out a way to reproduce
14214        // the actual situation to identify what is actually going on.
14215        if (false) {
14216            for (int i=0; i<mLaunchingProviders.size(); i++) {
14217                ContentProviderRecord cpr = (ContentProviderRecord)
14218                        mLaunchingProviders.get(i);
14219                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14220                    synchronized (cpr) {
14221                        cpr.launchingApp = null;
14222                        cpr.notifyAll();
14223                    }
14224                }
14225            }
14226        }
14227
14228        skipCurrentReceiverLocked(app);
14229
14230        // Unregister any receivers.
14231        for (int i=app.receivers.size()-1; i>=0; i--) {
14232            removeReceiverLocked(app.receivers.valueAt(i));
14233        }
14234        app.receivers.clear();
14235
14236        // If the app is undergoing backup, tell the backup manager about it
14237        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14238            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14239                    + mBackupTarget.appInfo + " died during backup");
14240            try {
14241                IBackupManager bm = IBackupManager.Stub.asInterface(
14242                        ServiceManager.getService(Context.BACKUP_SERVICE));
14243                bm.agentDisconnected(app.info.packageName);
14244            } catch (RemoteException e) {
14245                // can't happen; backup manager is local
14246            }
14247        }
14248
14249        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14250            ProcessChangeItem item = mPendingProcessChanges.get(i);
14251            if (item.pid == app.pid) {
14252                mPendingProcessChanges.remove(i);
14253                mAvailProcessChanges.add(item);
14254            }
14255        }
14256        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14257
14258        // If the caller is restarting this app, then leave it in its
14259        // current lists and let the caller take care of it.
14260        if (restarting) {
14261            return;
14262        }
14263
14264        if (!app.persistent || app.isolated) {
14265            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14266                    "Removing non-persistent process during cleanup: " + app);
14267            mProcessNames.remove(app.processName, app.uid);
14268            mIsolatedProcesses.remove(app.uid);
14269            if (mHeavyWeightProcess == app) {
14270                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14271                        mHeavyWeightProcess.userId, 0));
14272                mHeavyWeightProcess = null;
14273            }
14274        } else if (!app.removed) {
14275            // This app is persistent, so we need to keep its record around.
14276            // If it is not already on the pending app list, add it there
14277            // and start a new process for it.
14278            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14279                mPersistentStartingProcesses.add(app);
14280                restart = true;
14281            }
14282        }
14283        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14284                "Clean-up removing on hold: " + app);
14285        mProcessesOnHold.remove(app);
14286
14287        if (app == mHomeProcess) {
14288            mHomeProcess = null;
14289        }
14290        if (app == mPreviousProcess) {
14291            mPreviousProcess = null;
14292        }
14293
14294        if (restart && !app.isolated) {
14295            // We have components that still need to be running in the
14296            // process, so re-launch it.
14297            mProcessNames.put(app.processName, app.uid, app);
14298            startProcessLocked(app, "restart", app.processName);
14299        } else if (app.pid > 0 && app.pid != MY_PID) {
14300            // Goodbye!
14301            boolean removed;
14302            synchronized (mPidsSelfLocked) {
14303                mPidsSelfLocked.remove(app.pid);
14304                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14305            }
14306            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14307            if (app.isolated) {
14308                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14309            }
14310            app.setPid(0);
14311        }
14312    }
14313
14314    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14315        // Look through the content providers we are waiting to have launched,
14316        // and if any run in this process then either schedule a restart of
14317        // the process or kill the client waiting for it if this process has
14318        // gone bad.
14319        int NL = mLaunchingProviders.size();
14320        boolean restart = false;
14321        for (int i=0; i<NL; i++) {
14322            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14323            if (cpr.launchingApp == app) {
14324                if (!alwaysBad && !app.bad) {
14325                    restart = true;
14326                } else {
14327                    removeDyingProviderLocked(app, cpr, true);
14328                    // cpr should have been removed from mLaunchingProviders
14329                    NL = mLaunchingProviders.size();
14330                    i--;
14331                }
14332            }
14333        }
14334        return restart;
14335    }
14336
14337    // =========================================================
14338    // SERVICES
14339    // =========================================================
14340
14341    @Override
14342    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14343            int flags) {
14344        enforceNotIsolatedCaller("getServices");
14345        synchronized (this) {
14346            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14347        }
14348    }
14349
14350    @Override
14351    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14352        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14353        synchronized (this) {
14354            return mServices.getRunningServiceControlPanelLocked(name);
14355        }
14356    }
14357
14358    @Override
14359    public ComponentName startService(IApplicationThread caller, Intent service,
14360            String resolvedType, int userId) {
14361        enforceNotIsolatedCaller("startService");
14362        // Refuse possible leaked file descriptors
14363        if (service != null && service.hasFileDescriptors() == true) {
14364            throw new IllegalArgumentException("File descriptors passed in Intent");
14365        }
14366
14367        if (DEBUG_SERVICE)
14368            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14369        synchronized(this) {
14370            final int callingPid = Binder.getCallingPid();
14371            final int callingUid = Binder.getCallingUid();
14372            final long origId = Binder.clearCallingIdentity();
14373            ComponentName res = mServices.startServiceLocked(caller, service,
14374                    resolvedType, callingPid, callingUid, userId);
14375            Binder.restoreCallingIdentity(origId);
14376            return res;
14377        }
14378    }
14379
14380    ComponentName startServiceInPackage(int uid,
14381            Intent service, String resolvedType, int userId) {
14382        synchronized(this) {
14383            if (DEBUG_SERVICE)
14384                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14385            final long origId = Binder.clearCallingIdentity();
14386            ComponentName res = mServices.startServiceLocked(null, service,
14387                    resolvedType, -1, uid, userId);
14388            Binder.restoreCallingIdentity(origId);
14389            return res;
14390        }
14391    }
14392
14393    @Override
14394    public int stopService(IApplicationThread caller, Intent service,
14395            String resolvedType, int userId) {
14396        enforceNotIsolatedCaller("stopService");
14397        // Refuse possible leaked file descriptors
14398        if (service != null && service.hasFileDescriptors() == true) {
14399            throw new IllegalArgumentException("File descriptors passed in Intent");
14400        }
14401
14402        synchronized(this) {
14403            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14404        }
14405    }
14406
14407    @Override
14408    public IBinder peekService(Intent service, String resolvedType) {
14409        enforceNotIsolatedCaller("peekService");
14410        // Refuse possible leaked file descriptors
14411        if (service != null && service.hasFileDescriptors() == true) {
14412            throw new IllegalArgumentException("File descriptors passed in Intent");
14413        }
14414        synchronized(this) {
14415            return mServices.peekServiceLocked(service, resolvedType);
14416        }
14417    }
14418
14419    @Override
14420    public boolean stopServiceToken(ComponentName className, IBinder token,
14421            int startId) {
14422        synchronized(this) {
14423            return mServices.stopServiceTokenLocked(className, token, startId);
14424        }
14425    }
14426
14427    @Override
14428    public void setServiceForeground(ComponentName className, IBinder token,
14429            int id, Notification notification, boolean removeNotification) {
14430        synchronized(this) {
14431            mServices.setServiceForegroundLocked(className, token, id, notification,
14432                    removeNotification);
14433        }
14434    }
14435
14436    @Override
14437    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14438            boolean requireFull, String name, String callerPackage) {
14439        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14440                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14441    }
14442
14443    int unsafeConvertIncomingUser(int userId) {
14444        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14445                ? mCurrentUserId : userId;
14446    }
14447
14448    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14449            int allowMode, String name, String callerPackage) {
14450        final int callingUserId = UserHandle.getUserId(callingUid);
14451        if (callingUserId == userId) {
14452            return userId;
14453        }
14454
14455        // Note that we may be accessing mCurrentUserId outside of a lock...
14456        // shouldn't be a big deal, if this is being called outside
14457        // of a locked context there is intrinsically a race with
14458        // the value the caller will receive and someone else changing it.
14459        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14460        // we will switch to the calling user if access to the current user fails.
14461        int targetUserId = unsafeConvertIncomingUser(userId);
14462
14463        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14464            final boolean allow;
14465            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14466                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14467                // If the caller has this permission, they always pass go.  And collect $200.
14468                allow = true;
14469            } else if (allowMode == ALLOW_FULL_ONLY) {
14470                // We require full access, sucks to be you.
14471                allow = false;
14472            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14473                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14474                // If the caller does not have either permission, they are always doomed.
14475                allow = false;
14476            } else if (allowMode == ALLOW_NON_FULL) {
14477                // We are blanket allowing non-full access, you lucky caller!
14478                allow = true;
14479            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14480                // We may or may not allow this depending on whether the two users are
14481                // in the same profile.
14482                synchronized (mUserProfileGroupIdsSelfLocked) {
14483                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14484                            UserInfo.NO_PROFILE_GROUP_ID);
14485                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14486                            UserInfo.NO_PROFILE_GROUP_ID);
14487                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14488                            && callingProfile == targetProfile;
14489                }
14490            } else {
14491                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14492            }
14493            if (!allow) {
14494                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14495                    // In this case, they would like to just execute as their
14496                    // owner user instead of failing.
14497                    targetUserId = callingUserId;
14498                } else {
14499                    StringBuilder builder = new StringBuilder(128);
14500                    builder.append("Permission Denial: ");
14501                    builder.append(name);
14502                    if (callerPackage != null) {
14503                        builder.append(" from ");
14504                        builder.append(callerPackage);
14505                    }
14506                    builder.append(" asks to run as user ");
14507                    builder.append(userId);
14508                    builder.append(" but is calling from user ");
14509                    builder.append(UserHandle.getUserId(callingUid));
14510                    builder.append("; this requires ");
14511                    builder.append(INTERACT_ACROSS_USERS_FULL);
14512                    if (allowMode != ALLOW_FULL_ONLY) {
14513                        builder.append(" or ");
14514                        builder.append(INTERACT_ACROSS_USERS);
14515                    }
14516                    String msg = builder.toString();
14517                    Slog.w(TAG, msg);
14518                    throw new SecurityException(msg);
14519                }
14520            }
14521        }
14522        if (!allowAll && targetUserId < 0) {
14523            throw new IllegalArgumentException(
14524                    "Call does not support special user #" + targetUserId);
14525        }
14526        return targetUserId;
14527    }
14528
14529    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14530            String className, int flags) {
14531        boolean result = false;
14532        // For apps that don't have pre-defined UIDs, check for permission
14533        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14534            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14535                if (ActivityManager.checkUidPermission(
14536                        INTERACT_ACROSS_USERS,
14537                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14538                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14539                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14540                            + " requests FLAG_SINGLE_USER, but app does not hold "
14541                            + INTERACT_ACROSS_USERS;
14542                    Slog.w(TAG, msg);
14543                    throw new SecurityException(msg);
14544                }
14545                // Permission passed
14546                result = true;
14547            }
14548        } else if ("system".equals(componentProcessName)) {
14549            result = true;
14550        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14551                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14552            // Phone app is allowed to export singleuser providers.
14553            result = true;
14554        } else {
14555            // App with pre-defined UID, check if it's a persistent app
14556            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14557        }
14558        if (DEBUG_MU) {
14559            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14560                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14561        }
14562        return result;
14563    }
14564
14565    /**
14566     * Checks to see if the caller is in the same app as the singleton
14567     * component, or the component is in a special app. It allows special apps
14568     * to export singleton components but prevents exporting singleton
14569     * components for regular apps.
14570     */
14571    boolean isValidSingletonCall(int callingUid, int componentUid) {
14572        int componentAppId = UserHandle.getAppId(componentUid);
14573        return UserHandle.isSameApp(callingUid, componentUid)
14574                || componentAppId == Process.SYSTEM_UID
14575                || componentAppId == Process.PHONE_UID
14576                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14577                        == PackageManager.PERMISSION_GRANTED;
14578    }
14579
14580    public int bindService(IApplicationThread caller, IBinder token,
14581            Intent service, String resolvedType,
14582            IServiceConnection connection, int flags, int userId) {
14583        enforceNotIsolatedCaller("bindService");
14584        // Refuse possible leaked file descriptors
14585        if (service != null && service.hasFileDescriptors() == true) {
14586            throw new IllegalArgumentException("File descriptors passed in Intent");
14587        }
14588
14589        synchronized(this) {
14590            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14591                    connection, flags, userId);
14592        }
14593    }
14594
14595    public boolean unbindService(IServiceConnection connection) {
14596        synchronized (this) {
14597            return mServices.unbindServiceLocked(connection);
14598        }
14599    }
14600
14601    public void publishService(IBinder token, Intent intent, IBinder service) {
14602        // Refuse possible leaked file descriptors
14603        if (intent != null && intent.hasFileDescriptors() == true) {
14604            throw new IllegalArgumentException("File descriptors passed in Intent");
14605        }
14606
14607        synchronized(this) {
14608            if (!(token instanceof ServiceRecord)) {
14609                throw new IllegalArgumentException("Invalid service token");
14610            }
14611            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14612        }
14613    }
14614
14615    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14616        // Refuse possible leaked file descriptors
14617        if (intent != null && intent.hasFileDescriptors() == true) {
14618            throw new IllegalArgumentException("File descriptors passed in Intent");
14619        }
14620
14621        synchronized(this) {
14622            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14623        }
14624    }
14625
14626    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14627        synchronized(this) {
14628            if (!(token instanceof ServiceRecord)) {
14629                throw new IllegalArgumentException("Invalid service token");
14630            }
14631            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14632        }
14633    }
14634
14635    // =========================================================
14636    // BACKUP AND RESTORE
14637    // =========================================================
14638
14639    // Cause the target app to be launched if necessary and its backup agent
14640    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14641    // activity manager to announce its creation.
14642    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14643        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14644        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14645
14646        synchronized(this) {
14647            // !!! TODO: currently no check here that we're already bound
14648            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14649            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14650            synchronized (stats) {
14651                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14652            }
14653
14654            // Backup agent is now in use, its package can't be stopped.
14655            try {
14656                AppGlobals.getPackageManager().setPackageStoppedState(
14657                        app.packageName, false, UserHandle.getUserId(app.uid));
14658            } catch (RemoteException e) {
14659            } catch (IllegalArgumentException e) {
14660                Slog.w(TAG, "Failed trying to unstop package "
14661                        + app.packageName + ": " + e);
14662            }
14663
14664            BackupRecord r = new BackupRecord(ss, app, backupMode);
14665            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14666                    ? new ComponentName(app.packageName, app.backupAgentName)
14667                    : new ComponentName("android", "FullBackupAgent");
14668            // startProcessLocked() returns existing proc's record if it's already running
14669            ProcessRecord proc = startProcessLocked(app.processName, app,
14670                    false, 0, "backup", hostingName, false, false, false);
14671            if (proc == null) {
14672                Slog.e(TAG, "Unable to start backup agent process " + r);
14673                return false;
14674            }
14675
14676            r.app = proc;
14677            mBackupTarget = r;
14678            mBackupAppName = app.packageName;
14679
14680            // Try not to kill the process during backup
14681            updateOomAdjLocked(proc);
14682
14683            // If the process is already attached, schedule the creation of the backup agent now.
14684            // If it is not yet live, this will be done when it attaches to the framework.
14685            if (proc.thread != null) {
14686                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14687                try {
14688                    proc.thread.scheduleCreateBackupAgent(app,
14689                            compatibilityInfoForPackageLocked(app), backupMode);
14690                } catch (RemoteException e) {
14691                    // Will time out on the backup manager side
14692                }
14693            } else {
14694                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14695            }
14696            // Invariants: at this point, the target app process exists and the application
14697            // is either already running or in the process of coming up.  mBackupTarget and
14698            // mBackupAppName describe the app, so that when it binds back to the AM we
14699            // know that it's scheduled for a backup-agent operation.
14700        }
14701
14702        return true;
14703    }
14704
14705    @Override
14706    public void clearPendingBackup() {
14707        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14708        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14709
14710        synchronized (this) {
14711            mBackupTarget = null;
14712            mBackupAppName = null;
14713        }
14714    }
14715
14716    // A backup agent has just come up
14717    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14718        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14719                + " = " + agent);
14720
14721        synchronized(this) {
14722            if (!agentPackageName.equals(mBackupAppName)) {
14723                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14724                return;
14725            }
14726        }
14727
14728        long oldIdent = Binder.clearCallingIdentity();
14729        try {
14730            IBackupManager bm = IBackupManager.Stub.asInterface(
14731                    ServiceManager.getService(Context.BACKUP_SERVICE));
14732            bm.agentConnected(agentPackageName, agent);
14733        } catch (RemoteException e) {
14734            // can't happen; the backup manager service is local
14735        } catch (Exception e) {
14736            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14737            e.printStackTrace();
14738        } finally {
14739            Binder.restoreCallingIdentity(oldIdent);
14740        }
14741    }
14742
14743    // done with this agent
14744    public void unbindBackupAgent(ApplicationInfo appInfo) {
14745        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14746        if (appInfo == null) {
14747            Slog.w(TAG, "unbind backup agent for null app");
14748            return;
14749        }
14750
14751        synchronized(this) {
14752            try {
14753                if (mBackupAppName == null) {
14754                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14755                    return;
14756                }
14757
14758                if (!mBackupAppName.equals(appInfo.packageName)) {
14759                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14760                    return;
14761                }
14762
14763                // Not backing this app up any more; reset its OOM adjustment
14764                final ProcessRecord proc = mBackupTarget.app;
14765                updateOomAdjLocked(proc);
14766
14767                // If the app crashed during backup, 'thread' will be null here
14768                if (proc.thread != null) {
14769                    try {
14770                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14771                                compatibilityInfoForPackageLocked(appInfo));
14772                    } catch (Exception e) {
14773                        Slog.e(TAG, "Exception when unbinding backup agent:");
14774                        e.printStackTrace();
14775                    }
14776                }
14777            } finally {
14778                mBackupTarget = null;
14779                mBackupAppName = null;
14780            }
14781        }
14782    }
14783    // =========================================================
14784    // BROADCASTS
14785    // =========================================================
14786
14787    private final List getStickiesLocked(String action, IntentFilter filter,
14788            List cur, int userId) {
14789        final ContentResolver resolver = mContext.getContentResolver();
14790        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14791        if (stickies == null) {
14792            return cur;
14793        }
14794        final ArrayList<Intent> list = stickies.get(action);
14795        if (list == null) {
14796            return cur;
14797        }
14798        int N = list.size();
14799        for (int i=0; i<N; i++) {
14800            Intent intent = list.get(i);
14801            if (filter.match(resolver, intent, true, TAG) >= 0) {
14802                if (cur == null) {
14803                    cur = new ArrayList<Intent>();
14804                }
14805                cur.add(intent);
14806            }
14807        }
14808        return cur;
14809    }
14810
14811    boolean isPendingBroadcastProcessLocked(int pid) {
14812        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14813                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14814    }
14815
14816    void skipPendingBroadcastLocked(int pid) {
14817            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14818            for (BroadcastQueue queue : mBroadcastQueues) {
14819                queue.skipPendingBroadcastLocked(pid);
14820            }
14821    }
14822
14823    // The app just attached; send any pending broadcasts that it should receive
14824    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14825        boolean didSomething = false;
14826        for (BroadcastQueue queue : mBroadcastQueues) {
14827            didSomething |= queue.sendPendingBroadcastsLocked(app);
14828        }
14829        return didSomething;
14830    }
14831
14832    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14833            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14834        enforceNotIsolatedCaller("registerReceiver");
14835        int callingUid;
14836        int callingPid;
14837        synchronized(this) {
14838            ProcessRecord callerApp = null;
14839            if (caller != null) {
14840                callerApp = getRecordForAppLocked(caller);
14841                if (callerApp == null) {
14842                    throw new SecurityException(
14843                            "Unable to find app for caller " + caller
14844                            + " (pid=" + Binder.getCallingPid()
14845                            + ") when registering receiver " + receiver);
14846                }
14847                if (callerApp.info.uid != Process.SYSTEM_UID &&
14848                        !callerApp.pkgList.containsKey(callerPackage) &&
14849                        !"android".equals(callerPackage)) {
14850                    throw new SecurityException("Given caller package " + callerPackage
14851                            + " is not running in process " + callerApp);
14852                }
14853                callingUid = callerApp.info.uid;
14854                callingPid = callerApp.pid;
14855            } else {
14856                callerPackage = null;
14857                callingUid = Binder.getCallingUid();
14858                callingPid = Binder.getCallingPid();
14859            }
14860
14861            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14862                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14863
14864            List allSticky = null;
14865
14866            // Look for any matching sticky broadcasts...
14867            Iterator actions = filter.actionsIterator();
14868            if (actions != null) {
14869                while (actions.hasNext()) {
14870                    String action = (String)actions.next();
14871                    allSticky = getStickiesLocked(action, filter, allSticky,
14872                            UserHandle.USER_ALL);
14873                    allSticky = getStickiesLocked(action, filter, allSticky,
14874                            UserHandle.getUserId(callingUid));
14875                }
14876            } else {
14877                allSticky = getStickiesLocked(null, filter, allSticky,
14878                        UserHandle.USER_ALL);
14879                allSticky = getStickiesLocked(null, filter, allSticky,
14880                        UserHandle.getUserId(callingUid));
14881            }
14882
14883            // The first sticky in the list is returned directly back to
14884            // the client.
14885            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14886
14887            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14888                    + ": " + sticky);
14889
14890            if (receiver == null) {
14891                return sticky;
14892            }
14893
14894            ReceiverList rl
14895                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14896            if (rl == null) {
14897                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14898                        userId, receiver);
14899                if (rl.app != null) {
14900                    rl.app.receivers.add(rl);
14901                } else {
14902                    try {
14903                        receiver.asBinder().linkToDeath(rl, 0);
14904                    } catch (RemoteException e) {
14905                        return sticky;
14906                    }
14907                    rl.linkedToDeath = true;
14908                }
14909                mRegisteredReceivers.put(receiver.asBinder(), rl);
14910            } else if (rl.uid != callingUid) {
14911                throw new IllegalArgumentException(
14912                        "Receiver requested to register for uid " + callingUid
14913                        + " was previously registered for uid " + rl.uid);
14914            } else if (rl.pid != callingPid) {
14915                throw new IllegalArgumentException(
14916                        "Receiver requested to register for pid " + callingPid
14917                        + " was previously registered for pid " + rl.pid);
14918            } else if (rl.userId != userId) {
14919                throw new IllegalArgumentException(
14920                        "Receiver requested to register for user " + userId
14921                        + " was previously registered for user " + rl.userId);
14922            }
14923            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14924                    permission, callingUid, userId);
14925            rl.add(bf);
14926            if (!bf.debugCheck()) {
14927                Slog.w(TAG, "==> For Dynamic broadast");
14928            }
14929            mReceiverResolver.addFilter(bf);
14930
14931            // Enqueue broadcasts for all existing stickies that match
14932            // this filter.
14933            if (allSticky != null) {
14934                ArrayList receivers = new ArrayList();
14935                receivers.add(bf);
14936
14937                int N = allSticky.size();
14938                for (int i=0; i<N; i++) {
14939                    Intent intent = (Intent)allSticky.get(i);
14940                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14941                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14942                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14943                            null, null, false, true, true, -1);
14944                    queue.enqueueParallelBroadcastLocked(r);
14945                    queue.scheduleBroadcastsLocked();
14946                }
14947            }
14948
14949            return sticky;
14950        }
14951    }
14952
14953    public void unregisterReceiver(IIntentReceiver receiver) {
14954        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14955
14956        final long origId = Binder.clearCallingIdentity();
14957        try {
14958            boolean doTrim = false;
14959
14960            synchronized(this) {
14961                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14962                if (rl != null) {
14963                    if (rl.curBroadcast != null) {
14964                        BroadcastRecord r = rl.curBroadcast;
14965                        final boolean doNext = finishReceiverLocked(
14966                                receiver.asBinder(), r.resultCode, r.resultData,
14967                                r.resultExtras, r.resultAbort);
14968                        if (doNext) {
14969                            doTrim = true;
14970                            r.queue.processNextBroadcast(false);
14971                        }
14972                    }
14973
14974                    if (rl.app != null) {
14975                        rl.app.receivers.remove(rl);
14976                    }
14977                    removeReceiverLocked(rl);
14978                    if (rl.linkedToDeath) {
14979                        rl.linkedToDeath = false;
14980                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14981                    }
14982                }
14983            }
14984
14985            // If we actually concluded any broadcasts, we might now be able
14986            // to trim the recipients' apps from our working set
14987            if (doTrim) {
14988                trimApplications();
14989                return;
14990            }
14991
14992        } finally {
14993            Binder.restoreCallingIdentity(origId);
14994        }
14995    }
14996
14997    void removeReceiverLocked(ReceiverList rl) {
14998        mRegisteredReceivers.remove(rl.receiver.asBinder());
14999        int N = rl.size();
15000        for (int i=0; i<N; i++) {
15001            mReceiverResolver.removeFilter(rl.get(i));
15002        }
15003    }
15004
15005    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15006        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15007            ProcessRecord r = mLruProcesses.get(i);
15008            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15009                try {
15010                    r.thread.dispatchPackageBroadcast(cmd, packages);
15011                } catch (RemoteException ex) {
15012                }
15013            }
15014        }
15015    }
15016
15017    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15018            int[] users) {
15019        List<ResolveInfo> receivers = null;
15020        try {
15021            HashSet<ComponentName> singleUserReceivers = null;
15022            boolean scannedFirstReceivers = false;
15023            for (int user : users) {
15024                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15025                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15026                if (user != 0 && newReceivers != null) {
15027                    // If this is not the primary user, we need to check for
15028                    // any receivers that should be filtered out.
15029                    for (int i=0; i<newReceivers.size(); i++) {
15030                        ResolveInfo ri = newReceivers.get(i);
15031                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15032                            newReceivers.remove(i);
15033                            i--;
15034                        }
15035                    }
15036                }
15037                if (newReceivers != null && newReceivers.size() == 0) {
15038                    newReceivers = null;
15039                }
15040                if (receivers == null) {
15041                    receivers = newReceivers;
15042                } else if (newReceivers != null) {
15043                    // We need to concatenate the additional receivers
15044                    // found with what we have do far.  This would be easy,
15045                    // but we also need to de-dup any receivers that are
15046                    // singleUser.
15047                    if (!scannedFirstReceivers) {
15048                        // Collect any single user receivers we had already retrieved.
15049                        scannedFirstReceivers = true;
15050                        for (int i=0; i<receivers.size(); i++) {
15051                            ResolveInfo ri = receivers.get(i);
15052                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15053                                ComponentName cn = new ComponentName(
15054                                        ri.activityInfo.packageName, ri.activityInfo.name);
15055                                if (singleUserReceivers == null) {
15056                                    singleUserReceivers = new HashSet<ComponentName>();
15057                                }
15058                                singleUserReceivers.add(cn);
15059                            }
15060                        }
15061                    }
15062                    // Add the new results to the existing results, tracking
15063                    // and de-dupping single user receivers.
15064                    for (int i=0; i<newReceivers.size(); i++) {
15065                        ResolveInfo ri = newReceivers.get(i);
15066                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15067                            ComponentName cn = new ComponentName(
15068                                    ri.activityInfo.packageName, ri.activityInfo.name);
15069                            if (singleUserReceivers == null) {
15070                                singleUserReceivers = new HashSet<ComponentName>();
15071                            }
15072                            if (!singleUserReceivers.contains(cn)) {
15073                                singleUserReceivers.add(cn);
15074                                receivers.add(ri);
15075                            }
15076                        } else {
15077                            receivers.add(ri);
15078                        }
15079                    }
15080                }
15081            }
15082        } catch (RemoteException ex) {
15083            // pm is in same process, this will never happen.
15084        }
15085        return receivers;
15086    }
15087
15088    private final int broadcastIntentLocked(ProcessRecord callerApp,
15089            String callerPackage, Intent intent, String resolvedType,
15090            IIntentReceiver resultTo, int resultCode, String resultData,
15091            Bundle map, String requiredPermission, int appOp,
15092            boolean ordered, boolean sticky, int callingPid, int callingUid,
15093            int userId) {
15094        intent = new Intent(intent);
15095
15096        // By default broadcasts do not go to stopped apps.
15097        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15098
15099        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15100            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15101            + " ordered=" + ordered + " userid=" + userId);
15102        if ((resultTo != null) && !ordered) {
15103            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15104        }
15105
15106        userId = handleIncomingUser(callingPid, callingUid, userId,
15107                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15108
15109        // Make sure that the user who is receiving this broadcast is started.
15110        // If not, we will just skip it.
15111
15112
15113        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15114            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15115                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15116                Slog.w(TAG, "Skipping broadcast of " + intent
15117                        + ": user " + userId + " is stopped");
15118                return ActivityManager.BROADCAST_SUCCESS;
15119            }
15120        }
15121
15122        /*
15123         * Prevent non-system code (defined here to be non-persistent
15124         * processes) from sending protected broadcasts.
15125         */
15126        int callingAppId = UserHandle.getAppId(callingUid);
15127        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15128            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15129            || callingAppId == Process.NFC_UID || callingUid == 0) {
15130            // Always okay.
15131        } else if (callerApp == null || !callerApp.persistent) {
15132            try {
15133                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15134                        intent.getAction())) {
15135                    String msg = "Permission Denial: not allowed to send broadcast "
15136                            + intent.getAction() + " from pid="
15137                            + callingPid + ", uid=" + callingUid;
15138                    Slog.w(TAG, msg);
15139                    throw new SecurityException(msg);
15140                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15141                    // Special case for compatibility: we don't want apps to send this,
15142                    // but historically it has not been protected and apps may be using it
15143                    // to poke their own app widget.  So, instead of making it protected,
15144                    // just limit it to the caller.
15145                    if (callerApp == null) {
15146                        String msg = "Permission Denial: not allowed to send broadcast "
15147                                + intent.getAction() + " from unknown caller.";
15148                        Slog.w(TAG, msg);
15149                        throw new SecurityException(msg);
15150                    } else if (intent.getComponent() != null) {
15151                        // They are good enough to send to an explicit component...  verify
15152                        // it is being sent to the calling app.
15153                        if (!intent.getComponent().getPackageName().equals(
15154                                callerApp.info.packageName)) {
15155                            String msg = "Permission Denial: not allowed to send broadcast "
15156                                    + intent.getAction() + " to "
15157                                    + intent.getComponent().getPackageName() + " from "
15158                                    + callerApp.info.packageName;
15159                            Slog.w(TAG, msg);
15160                            throw new SecurityException(msg);
15161                        }
15162                    } else {
15163                        // Limit broadcast to their own package.
15164                        intent.setPackage(callerApp.info.packageName);
15165                    }
15166                }
15167            } catch (RemoteException e) {
15168                Slog.w(TAG, "Remote exception", e);
15169                return ActivityManager.BROADCAST_SUCCESS;
15170            }
15171        }
15172
15173        // Handle special intents: if this broadcast is from the package
15174        // manager about a package being removed, we need to remove all of
15175        // its activities from the history stack.
15176        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15177                intent.getAction());
15178        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15179                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15180                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15181                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15182                || uidRemoved) {
15183            if (checkComponentPermission(
15184                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15185                    callingPid, callingUid, -1, true)
15186                    == PackageManager.PERMISSION_GRANTED) {
15187                if (uidRemoved) {
15188                    final Bundle intentExtras = intent.getExtras();
15189                    final int uid = intentExtras != null
15190                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15191                    if (uid >= 0) {
15192                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15193                        synchronized (bs) {
15194                            bs.removeUidStatsLocked(uid);
15195                        }
15196                        mAppOpsService.uidRemoved(uid);
15197                    }
15198                } else {
15199                    // If resources are unavailable just force stop all
15200                    // those packages and flush the attribute cache as well.
15201                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15202                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15203                        if (list != null && (list.length > 0)) {
15204                            for (String pkg : list) {
15205                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15206                                        "storage unmount");
15207                            }
15208                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15209                            sendPackageBroadcastLocked(
15210                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15211                        }
15212                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15213                            intent.getAction())) {
15214                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15215                    } else {
15216                        Uri data = intent.getData();
15217                        String ssp;
15218                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15219                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15220                                    intent.getAction());
15221                            boolean fullUninstall = removed &&
15222                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15223                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15224                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15225                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15226                                        false, fullUninstall, userId,
15227                                        removed ? "pkg removed" : "pkg changed");
15228                            }
15229                            if (removed) {
15230                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15231                                        new String[] {ssp}, userId);
15232                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15233                                    mAppOpsService.packageRemoved(
15234                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15235
15236                                    // Remove all permissions granted from/to this package
15237                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15238                                }
15239                            }
15240                        }
15241                    }
15242                }
15243            } else {
15244                String msg = "Permission Denial: " + intent.getAction()
15245                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15246                        + ", uid=" + callingUid + ")"
15247                        + " requires "
15248                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15249                Slog.w(TAG, msg);
15250                throw new SecurityException(msg);
15251            }
15252
15253        // Special case for adding a package: by default turn on compatibility
15254        // mode.
15255        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15256            Uri data = intent.getData();
15257            String ssp;
15258            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15259                mCompatModePackages.handlePackageAddedLocked(ssp,
15260                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15261            }
15262        }
15263
15264        /*
15265         * If this is the time zone changed action, queue up a message that will reset the timezone
15266         * of all currently running processes. This message will get queued up before the broadcast
15267         * happens.
15268         */
15269        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15270            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15271        }
15272
15273        /*
15274         * If the user set the time, let all running processes know.
15275         */
15276        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15277            final int is24Hour = intent.getBooleanExtra(
15278                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15279            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15280            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15281            synchronized (stats) {
15282                stats.noteCurrentTimeChangedLocked();
15283            }
15284        }
15285
15286        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15287            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15288        }
15289
15290        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15291            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15292            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15293        }
15294
15295        // Add to the sticky list if requested.
15296        if (sticky) {
15297            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15298                    callingPid, callingUid)
15299                    != PackageManager.PERMISSION_GRANTED) {
15300                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15301                        + callingPid + ", uid=" + callingUid
15302                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15303                Slog.w(TAG, msg);
15304                throw new SecurityException(msg);
15305            }
15306            if (requiredPermission != null) {
15307                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15308                        + " and enforce permission " + requiredPermission);
15309                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15310            }
15311            if (intent.getComponent() != null) {
15312                throw new SecurityException(
15313                        "Sticky broadcasts can't target a specific component");
15314            }
15315            // We use userId directly here, since the "all" target is maintained
15316            // as a separate set of sticky broadcasts.
15317            if (userId != UserHandle.USER_ALL) {
15318                // But first, if this is not a broadcast to all users, then
15319                // make sure it doesn't conflict with an existing broadcast to
15320                // all users.
15321                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15322                        UserHandle.USER_ALL);
15323                if (stickies != null) {
15324                    ArrayList<Intent> list = stickies.get(intent.getAction());
15325                    if (list != null) {
15326                        int N = list.size();
15327                        int i;
15328                        for (i=0; i<N; i++) {
15329                            if (intent.filterEquals(list.get(i))) {
15330                                throw new IllegalArgumentException(
15331                                        "Sticky broadcast " + intent + " for user "
15332                                        + userId + " conflicts with existing global broadcast");
15333                            }
15334                        }
15335                    }
15336                }
15337            }
15338            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15339            if (stickies == null) {
15340                stickies = new ArrayMap<String, ArrayList<Intent>>();
15341                mStickyBroadcasts.put(userId, stickies);
15342            }
15343            ArrayList<Intent> list = stickies.get(intent.getAction());
15344            if (list == null) {
15345                list = new ArrayList<Intent>();
15346                stickies.put(intent.getAction(), list);
15347            }
15348            int N = list.size();
15349            int i;
15350            for (i=0; i<N; i++) {
15351                if (intent.filterEquals(list.get(i))) {
15352                    // This sticky already exists, replace it.
15353                    list.set(i, new Intent(intent));
15354                    break;
15355                }
15356            }
15357            if (i >= N) {
15358                list.add(new Intent(intent));
15359            }
15360        }
15361
15362        int[] users;
15363        if (userId == UserHandle.USER_ALL) {
15364            // Caller wants broadcast to go to all started users.
15365            users = mStartedUserArray;
15366        } else {
15367            // Caller wants broadcast to go to one specific user.
15368            users = new int[] {userId};
15369        }
15370
15371        // Figure out who all will receive this broadcast.
15372        List receivers = null;
15373        List<BroadcastFilter> registeredReceivers = null;
15374        // Need to resolve the intent to interested receivers...
15375        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15376                 == 0) {
15377            receivers = collectReceiverComponents(intent, resolvedType, users);
15378        }
15379        if (intent.getComponent() == null) {
15380            registeredReceivers = mReceiverResolver.queryIntent(intent,
15381                    resolvedType, false, userId);
15382        }
15383
15384        final boolean replacePending =
15385                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15386
15387        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15388                + " replacePending=" + replacePending);
15389
15390        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15391        if (!ordered && NR > 0) {
15392            // If we are not serializing this broadcast, then send the
15393            // registered receivers separately so they don't wait for the
15394            // components to be launched.
15395            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15396            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15397                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15398                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15399                    ordered, sticky, false, userId);
15400            if (DEBUG_BROADCAST) Slog.v(
15401                    TAG, "Enqueueing parallel broadcast " + r);
15402            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15403            if (!replaced) {
15404                queue.enqueueParallelBroadcastLocked(r);
15405                queue.scheduleBroadcastsLocked();
15406            }
15407            registeredReceivers = null;
15408            NR = 0;
15409        }
15410
15411        // Merge into one list.
15412        int ir = 0;
15413        if (receivers != null) {
15414            // A special case for PACKAGE_ADDED: do not allow the package
15415            // being added to see this broadcast.  This prevents them from
15416            // using this as a back door to get run as soon as they are
15417            // installed.  Maybe in the future we want to have a special install
15418            // broadcast or such for apps, but we'd like to deliberately make
15419            // this decision.
15420            String skipPackages[] = null;
15421            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15422                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15423                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15424                Uri data = intent.getData();
15425                if (data != null) {
15426                    String pkgName = data.getSchemeSpecificPart();
15427                    if (pkgName != null) {
15428                        skipPackages = new String[] { pkgName };
15429                    }
15430                }
15431            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15432                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15433            }
15434            if (skipPackages != null && (skipPackages.length > 0)) {
15435                for (String skipPackage : skipPackages) {
15436                    if (skipPackage != null) {
15437                        int NT = receivers.size();
15438                        for (int it=0; it<NT; it++) {
15439                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15440                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15441                                receivers.remove(it);
15442                                it--;
15443                                NT--;
15444                            }
15445                        }
15446                    }
15447                }
15448            }
15449
15450            int NT = receivers != null ? receivers.size() : 0;
15451            int it = 0;
15452            ResolveInfo curt = null;
15453            BroadcastFilter curr = null;
15454            while (it < NT && ir < NR) {
15455                if (curt == null) {
15456                    curt = (ResolveInfo)receivers.get(it);
15457                }
15458                if (curr == null) {
15459                    curr = registeredReceivers.get(ir);
15460                }
15461                if (curr.getPriority() >= curt.priority) {
15462                    // Insert this broadcast record into the final list.
15463                    receivers.add(it, curr);
15464                    ir++;
15465                    curr = null;
15466                    it++;
15467                    NT++;
15468                } else {
15469                    // Skip to the next ResolveInfo in the final list.
15470                    it++;
15471                    curt = null;
15472                }
15473            }
15474        }
15475        while (ir < NR) {
15476            if (receivers == null) {
15477                receivers = new ArrayList();
15478            }
15479            receivers.add(registeredReceivers.get(ir));
15480            ir++;
15481        }
15482
15483        if ((receivers != null && receivers.size() > 0)
15484                || resultTo != null) {
15485            BroadcastQueue queue = broadcastQueueForIntent(intent);
15486            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15487                    callerPackage, callingPid, callingUid, resolvedType,
15488                    requiredPermission, appOp, receivers, resultTo, resultCode,
15489                    resultData, map, ordered, sticky, false, userId);
15490            if (DEBUG_BROADCAST) Slog.v(
15491                    TAG, "Enqueueing ordered broadcast " + r
15492                    + ": prev had " + queue.mOrderedBroadcasts.size());
15493            if (DEBUG_BROADCAST) {
15494                int seq = r.intent.getIntExtra("seq", -1);
15495                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15496            }
15497            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15498            if (!replaced) {
15499                queue.enqueueOrderedBroadcastLocked(r);
15500                queue.scheduleBroadcastsLocked();
15501            }
15502        }
15503
15504        return ActivityManager.BROADCAST_SUCCESS;
15505    }
15506
15507    final Intent verifyBroadcastLocked(Intent intent) {
15508        // Refuse possible leaked file descriptors
15509        if (intent != null && intent.hasFileDescriptors() == true) {
15510            throw new IllegalArgumentException("File descriptors passed in Intent");
15511        }
15512
15513        int flags = intent.getFlags();
15514
15515        if (!mProcessesReady) {
15516            // if the caller really truly claims to know what they're doing, go
15517            // ahead and allow the broadcast without launching any receivers
15518            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15519                intent = new Intent(intent);
15520                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15521            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15522                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15523                        + " before boot completion");
15524                throw new IllegalStateException("Cannot broadcast before boot completed");
15525            }
15526        }
15527
15528        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15529            throw new IllegalArgumentException(
15530                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15531        }
15532
15533        return intent;
15534    }
15535
15536    public final int broadcastIntent(IApplicationThread caller,
15537            Intent intent, String resolvedType, IIntentReceiver resultTo,
15538            int resultCode, String resultData, Bundle map,
15539            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15540        enforceNotIsolatedCaller("broadcastIntent");
15541        synchronized(this) {
15542            intent = verifyBroadcastLocked(intent);
15543
15544            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15545            final int callingPid = Binder.getCallingPid();
15546            final int callingUid = Binder.getCallingUid();
15547            final long origId = Binder.clearCallingIdentity();
15548            int res = broadcastIntentLocked(callerApp,
15549                    callerApp != null ? callerApp.info.packageName : null,
15550                    intent, resolvedType, resultTo,
15551                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15552                    callingPid, callingUid, userId);
15553            Binder.restoreCallingIdentity(origId);
15554            return res;
15555        }
15556    }
15557
15558    int broadcastIntentInPackage(String packageName, int uid,
15559            Intent intent, String resolvedType, IIntentReceiver resultTo,
15560            int resultCode, String resultData, Bundle map,
15561            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15562        synchronized(this) {
15563            intent = verifyBroadcastLocked(intent);
15564
15565            final long origId = Binder.clearCallingIdentity();
15566            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15567                    resultTo, resultCode, resultData, map, requiredPermission,
15568                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15569            Binder.restoreCallingIdentity(origId);
15570            return res;
15571        }
15572    }
15573
15574    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15575        // Refuse possible leaked file descriptors
15576        if (intent != null && intent.hasFileDescriptors() == true) {
15577            throw new IllegalArgumentException("File descriptors passed in Intent");
15578        }
15579
15580        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15581                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15582
15583        synchronized(this) {
15584            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15585                    != PackageManager.PERMISSION_GRANTED) {
15586                String msg = "Permission Denial: unbroadcastIntent() from pid="
15587                        + Binder.getCallingPid()
15588                        + ", uid=" + Binder.getCallingUid()
15589                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15590                Slog.w(TAG, msg);
15591                throw new SecurityException(msg);
15592            }
15593            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15594            if (stickies != null) {
15595                ArrayList<Intent> list = stickies.get(intent.getAction());
15596                if (list != null) {
15597                    int N = list.size();
15598                    int i;
15599                    for (i=0; i<N; i++) {
15600                        if (intent.filterEquals(list.get(i))) {
15601                            list.remove(i);
15602                            break;
15603                        }
15604                    }
15605                    if (list.size() <= 0) {
15606                        stickies.remove(intent.getAction());
15607                    }
15608                }
15609                if (stickies.size() <= 0) {
15610                    mStickyBroadcasts.remove(userId);
15611                }
15612            }
15613        }
15614    }
15615
15616    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15617            String resultData, Bundle resultExtras, boolean resultAbort) {
15618        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15619        if (r == null) {
15620            Slog.w(TAG, "finishReceiver called but not found on queue");
15621            return false;
15622        }
15623
15624        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15625    }
15626
15627    void backgroundServicesFinishedLocked(int userId) {
15628        for (BroadcastQueue queue : mBroadcastQueues) {
15629            queue.backgroundServicesFinishedLocked(userId);
15630        }
15631    }
15632
15633    public void finishReceiver(IBinder who, int resultCode, String resultData,
15634            Bundle resultExtras, boolean resultAbort) {
15635        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15636
15637        // Refuse possible leaked file descriptors
15638        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15639            throw new IllegalArgumentException("File descriptors passed in Bundle");
15640        }
15641
15642        final long origId = Binder.clearCallingIdentity();
15643        try {
15644            boolean doNext = false;
15645            BroadcastRecord r;
15646
15647            synchronized(this) {
15648                r = broadcastRecordForReceiverLocked(who);
15649                if (r != null) {
15650                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15651                        resultData, resultExtras, resultAbort, true);
15652                }
15653            }
15654
15655            if (doNext) {
15656                r.queue.processNextBroadcast(false);
15657            }
15658            trimApplications();
15659        } finally {
15660            Binder.restoreCallingIdentity(origId);
15661        }
15662    }
15663
15664    // =========================================================
15665    // INSTRUMENTATION
15666    // =========================================================
15667
15668    public boolean startInstrumentation(ComponentName className,
15669            String profileFile, int flags, Bundle arguments,
15670            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15671            int userId, String abiOverride) {
15672        enforceNotIsolatedCaller("startInstrumentation");
15673        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15674                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15675        // Refuse possible leaked file descriptors
15676        if (arguments != null && arguments.hasFileDescriptors()) {
15677            throw new IllegalArgumentException("File descriptors passed in Bundle");
15678        }
15679
15680        synchronized(this) {
15681            InstrumentationInfo ii = null;
15682            ApplicationInfo ai = null;
15683            try {
15684                ii = mContext.getPackageManager().getInstrumentationInfo(
15685                    className, STOCK_PM_FLAGS);
15686                ai = AppGlobals.getPackageManager().getApplicationInfo(
15687                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15688            } catch (PackageManager.NameNotFoundException e) {
15689            } catch (RemoteException e) {
15690            }
15691            if (ii == null) {
15692                reportStartInstrumentationFailure(watcher, className,
15693                        "Unable to find instrumentation info for: " + className);
15694                return false;
15695            }
15696            if (ai == null) {
15697                reportStartInstrumentationFailure(watcher, className,
15698                        "Unable to find instrumentation target package: " + ii.targetPackage);
15699                return false;
15700            }
15701
15702            int match = mContext.getPackageManager().checkSignatures(
15703                    ii.targetPackage, ii.packageName);
15704            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15705                String msg = "Permission Denial: starting instrumentation "
15706                        + className + " from pid="
15707                        + Binder.getCallingPid()
15708                        + ", uid=" + Binder.getCallingPid()
15709                        + " not allowed because package " + ii.packageName
15710                        + " does not have a signature matching the target "
15711                        + ii.targetPackage;
15712                reportStartInstrumentationFailure(watcher, className, msg);
15713                throw new SecurityException(msg);
15714            }
15715
15716            final long origId = Binder.clearCallingIdentity();
15717            // Instrumentation can kill and relaunch even persistent processes
15718            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15719                    "start instr");
15720            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15721            app.instrumentationClass = className;
15722            app.instrumentationInfo = ai;
15723            app.instrumentationProfileFile = profileFile;
15724            app.instrumentationArguments = arguments;
15725            app.instrumentationWatcher = watcher;
15726            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15727            app.instrumentationResultClass = className;
15728            Binder.restoreCallingIdentity(origId);
15729        }
15730
15731        return true;
15732    }
15733
15734    /**
15735     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15736     * error to the logs, but if somebody is watching, send the report there too.  This enables
15737     * the "am" command to report errors with more information.
15738     *
15739     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15740     * @param cn The component name of the instrumentation.
15741     * @param report The error report.
15742     */
15743    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15744            ComponentName cn, String report) {
15745        Slog.w(TAG, report);
15746        try {
15747            if (watcher != null) {
15748                Bundle results = new Bundle();
15749                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15750                results.putString("Error", report);
15751                watcher.instrumentationStatus(cn, -1, results);
15752            }
15753        } catch (RemoteException e) {
15754            Slog.w(TAG, e);
15755        }
15756    }
15757
15758    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15759        if (app.instrumentationWatcher != null) {
15760            try {
15761                // NOTE:  IInstrumentationWatcher *must* be oneway here
15762                app.instrumentationWatcher.instrumentationFinished(
15763                    app.instrumentationClass,
15764                    resultCode,
15765                    results);
15766            } catch (RemoteException e) {
15767            }
15768        }
15769        if (app.instrumentationUiAutomationConnection != null) {
15770            try {
15771                app.instrumentationUiAutomationConnection.shutdown();
15772            } catch (RemoteException re) {
15773                /* ignore */
15774            }
15775            // Only a UiAutomation can set this flag and now that
15776            // it is finished we make sure it is reset to its default.
15777            mUserIsMonkey = false;
15778        }
15779        app.instrumentationWatcher = null;
15780        app.instrumentationUiAutomationConnection = null;
15781        app.instrumentationClass = null;
15782        app.instrumentationInfo = null;
15783        app.instrumentationProfileFile = null;
15784        app.instrumentationArguments = null;
15785
15786        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15787                "finished inst");
15788    }
15789
15790    public void finishInstrumentation(IApplicationThread target,
15791            int resultCode, Bundle results) {
15792        int userId = UserHandle.getCallingUserId();
15793        // Refuse possible leaked file descriptors
15794        if (results != null && results.hasFileDescriptors()) {
15795            throw new IllegalArgumentException("File descriptors passed in Intent");
15796        }
15797
15798        synchronized(this) {
15799            ProcessRecord app = getRecordForAppLocked(target);
15800            if (app == null) {
15801                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15802                return;
15803            }
15804            final long origId = Binder.clearCallingIdentity();
15805            finishInstrumentationLocked(app, resultCode, results);
15806            Binder.restoreCallingIdentity(origId);
15807        }
15808    }
15809
15810    // =========================================================
15811    // CONFIGURATION
15812    // =========================================================
15813
15814    public ConfigurationInfo getDeviceConfigurationInfo() {
15815        ConfigurationInfo config = new ConfigurationInfo();
15816        synchronized (this) {
15817            config.reqTouchScreen = mConfiguration.touchscreen;
15818            config.reqKeyboardType = mConfiguration.keyboard;
15819            config.reqNavigation = mConfiguration.navigation;
15820            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15821                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15822                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15823            }
15824            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15825                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15826                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15827            }
15828            config.reqGlEsVersion = GL_ES_VERSION;
15829        }
15830        return config;
15831    }
15832
15833    ActivityStack getFocusedStack() {
15834        return mStackSupervisor.getFocusedStack();
15835    }
15836
15837    public Configuration getConfiguration() {
15838        Configuration ci;
15839        synchronized(this) {
15840            ci = new Configuration(mConfiguration);
15841        }
15842        return ci;
15843    }
15844
15845    public void updatePersistentConfiguration(Configuration values) {
15846        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15847                "updateConfiguration()");
15848        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15849                "updateConfiguration()");
15850        if (values == null) {
15851            throw new NullPointerException("Configuration must not be null");
15852        }
15853
15854        synchronized(this) {
15855            final long origId = Binder.clearCallingIdentity();
15856            updateConfigurationLocked(values, null, true, false);
15857            Binder.restoreCallingIdentity(origId);
15858        }
15859    }
15860
15861    public void updateConfiguration(Configuration values) {
15862        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15863                "updateConfiguration()");
15864
15865        synchronized(this) {
15866            if (values == null && mWindowManager != null) {
15867                // sentinel: fetch the current configuration from the window manager
15868                values = mWindowManager.computeNewConfiguration();
15869            }
15870
15871            if (mWindowManager != null) {
15872                mProcessList.applyDisplaySize(mWindowManager);
15873            }
15874
15875            final long origId = Binder.clearCallingIdentity();
15876            if (values != null) {
15877                Settings.System.clearConfiguration(values);
15878            }
15879            updateConfigurationLocked(values, null, false, false);
15880            Binder.restoreCallingIdentity(origId);
15881        }
15882    }
15883
15884    /**
15885     * Do either or both things: (1) change the current configuration, and (2)
15886     * make sure the given activity is running with the (now) current
15887     * configuration.  Returns true if the activity has been left running, or
15888     * false if <var>starting</var> is being destroyed to match the new
15889     * configuration.
15890     * @param persistent TODO
15891     */
15892    boolean updateConfigurationLocked(Configuration values,
15893            ActivityRecord starting, boolean persistent, boolean initLocale) {
15894        int changes = 0;
15895
15896        if (values != null) {
15897            Configuration newConfig = new Configuration(mConfiguration);
15898            changes = newConfig.updateFrom(values);
15899            if (changes != 0) {
15900                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15901                    Slog.i(TAG, "Updating configuration to: " + values);
15902                }
15903
15904                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15905
15906                if (values.locale != null && !initLocale) {
15907                    saveLocaleLocked(values.locale,
15908                                     !values.locale.equals(mConfiguration.locale),
15909                                     values.userSetLocale);
15910                }
15911
15912                mConfigurationSeq++;
15913                if (mConfigurationSeq <= 0) {
15914                    mConfigurationSeq = 1;
15915                }
15916                newConfig.seq = mConfigurationSeq;
15917                mConfiguration = newConfig;
15918                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15919                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15920                //mUsageStatsService.noteStartConfig(newConfig);
15921
15922                final Configuration configCopy = new Configuration(mConfiguration);
15923
15924                // TODO: If our config changes, should we auto dismiss any currently
15925                // showing dialogs?
15926                mShowDialogs = shouldShowDialogs(newConfig);
15927
15928                AttributeCache ac = AttributeCache.instance();
15929                if (ac != null) {
15930                    ac.updateConfiguration(configCopy);
15931                }
15932
15933                // Make sure all resources in our process are updated
15934                // right now, so that anyone who is going to retrieve
15935                // resource values after we return will be sure to get
15936                // the new ones.  This is especially important during
15937                // boot, where the first config change needs to guarantee
15938                // all resources have that config before following boot
15939                // code is executed.
15940                mSystemThread.applyConfigurationToResources(configCopy);
15941
15942                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15943                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15944                    msg.obj = new Configuration(configCopy);
15945                    mHandler.sendMessage(msg);
15946                }
15947
15948                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15949                    ProcessRecord app = mLruProcesses.get(i);
15950                    try {
15951                        if (app.thread != null) {
15952                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15953                                    + app.processName + " new config " + mConfiguration);
15954                            app.thread.scheduleConfigurationChanged(configCopy);
15955                        }
15956                    } catch (Exception e) {
15957                    }
15958                }
15959                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15960                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15961                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15962                        | Intent.FLAG_RECEIVER_FOREGROUND);
15963                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15964                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15965                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15966                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15967                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15968                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15969                    broadcastIntentLocked(null, null, intent,
15970                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15971                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15972                }
15973            }
15974        }
15975
15976        boolean kept = true;
15977        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15978        // mainStack is null during startup.
15979        if (mainStack != null) {
15980            if (changes != 0 && starting == null) {
15981                // If the configuration changed, and the caller is not already
15982                // in the process of starting an activity, then find the top
15983                // activity to check if its configuration needs to change.
15984                starting = mainStack.topRunningActivityLocked(null);
15985            }
15986
15987            if (starting != null) {
15988                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15989                // And we need to make sure at this point that all other activities
15990                // are made visible with the correct configuration.
15991                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15992            }
15993        }
15994
15995        if (values != null && mWindowManager != null) {
15996            mWindowManager.setNewConfiguration(mConfiguration);
15997        }
15998
15999        return kept;
16000    }
16001
16002    /**
16003     * Decide based on the configuration whether we should shouw the ANR,
16004     * crash, etc dialogs.  The idea is that if there is no affordnace to
16005     * press the on-screen buttons, we shouldn't show the dialog.
16006     *
16007     * A thought: SystemUI might also want to get told about this, the Power
16008     * dialog / global actions also might want different behaviors.
16009     */
16010    private static final boolean shouldShowDialogs(Configuration config) {
16011        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16012                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16013    }
16014
16015    /**
16016     * Save the locale.  You must be inside a synchronized (this) block.
16017     */
16018    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16019        if(isDiff) {
16020            SystemProperties.set("user.language", l.getLanguage());
16021            SystemProperties.set("user.region", l.getCountry());
16022        }
16023
16024        if(isPersist) {
16025            SystemProperties.set("persist.sys.language", l.getLanguage());
16026            SystemProperties.set("persist.sys.country", l.getCountry());
16027            SystemProperties.set("persist.sys.localevar", l.getVariant());
16028        }
16029    }
16030
16031    @Override
16032    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16033        synchronized (this) {
16034            ActivityRecord srec = ActivityRecord.forToken(token);
16035            if (srec.task != null && srec.task.stack != null) {
16036                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16037            }
16038        }
16039        return false;
16040    }
16041
16042    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16043            Intent resultData) {
16044
16045        synchronized (this) {
16046            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16047            if (stack != null) {
16048                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16049            }
16050            return false;
16051        }
16052    }
16053
16054    public int getLaunchedFromUid(IBinder activityToken) {
16055        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16056        if (srec == null) {
16057            return -1;
16058        }
16059        return srec.launchedFromUid;
16060    }
16061
16062    public String getLaunchedFromPackage(IBinder activityToken) {
16063        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16064        if (srec == null) {
16065            return null;
16066        }
16067        return srec.launchedFromPackage;
16068    }
16069
16070    // =========================================================
16071    // LIFETIME MANAGEMENT
16072    // =========================================================
16073
16074    // Returns which broadcast queue the app is the current [or imminent] receiver
16075    // on, or 'null' if the app is not an active broadcast recipient.
16076    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16077        BroadcastRecord r = app.curReceiver;
16078        if (r != null) {
16079            return r.queue;
16080        }
16081
16082        // It's not the current receiver, but it might be starting up to become one
16083        synchronized (this) {
16084            for (BroadcastQueue queue : mBroadcastQueues) {
16085                r = queue.mPendingBroadcast;
16086                if (r != null && r.curApp == app) {
16087                    // found it; report which queue it's in
16088                    return queue;
16089                }
16090            }
16091        }
16092
16093        return null;
16094    }
16095
16096    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16097            boolean doingAll, long now) {
16098        if (mAdjSeq == app.adjSeq) {
16099            // This adjustment has already been computed.
16100            return app.curRawAdj;
16101        }
16102
16103        if (app.thread == null) {
16104            app.adjSeq = mAdjSeq;
16105            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16106            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16107            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16108        }
16109
16110        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16111        app.adjSource = null;
16112        app.adjTarget = null;
16113        app.empty = false;
16114        app.cached = false;
16115
16116        final int activitiesSize = app.activities.size();
16117
16118        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16119            // The max adjustment doesn't allow this app to be anything
16120            // below foreground, so it is not worth doing work for it.
16121            app.adjType = "fixed";
16122            app.adjSeq = mAdjSeq;
16123            app.curRawAdj = app.maxAdj;
16124            app.foregroundActivities = false;
16125            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16126            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16127            // System processes can do UI, and when they do we want to have
16128            // them trim their memory after the user leaves the UI.  To
16129            // facilitate this, here we need to determine whether or not it
16130            // is currently showing UI.
16131            app.systemNoUi = true;
16132            if (app == TOP_APP) {
16133                app.systemNoUi = false;
16134            } else if (activitiesSize > 0) {
16135                for (int j = 0; j < activitiesSize; j++) {
16136                    final ActivityRecord r = app.activities.get(j);
16137                    if (r.visible) {
16138                        app.systemNoUi = false;
16139                    }
16140                }
16141            }
16142            if (!app.systemNoUi) {
16143                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16144            }
16145            return (app.curAdj=app.maxAdj);
16146        }
16147
16148        app.systemNoUi = false;
16149
16150        // Determine the importance of the process, starting with most
16151        // important to least, and assign an appropriate OOM adjustment.
16152        int adj;
16153        int schedGroup;
16154        int procState;
16155        boolean foregroundActivities = false;
16156        BroadcastQueue queue;
16157        if (app == TOP_APP) {
16158            // The last app on the list is the foreground app.
16159            adj = ProcessList.FOREGROUND_APP_ADJ;
16160            schedGroup = Process.THREAD_GROUP_DEFAULT;
16161            app.adjType = "top-activity";
16162            foregroundActivities = true;
16163            procState = ActivityManager.PROCESS_STATE_TOP;
16164        } else if (app.instrumentationClass != null) {
16165            // Don't want to kill running instrumentation.
16166            adj = ProcessList.FOREGROUND_APP_ADJ;
16167            schedGroup = Process.THREAD_GROUP_DEFAULT;
16168            app.adjType = "instrumentation";
16169            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16170        } else if ((queue = isReceivingBroadcast(app)) != null) {
16171            // An app that is currently receiving a broadcast also
16172            // counts as being in the foreground for OOM killer purposes.
16173            // It's placed in a sched group based on the nature of the
16174            // broadcast as reflected by which queue it's active in.
16175            adj = ProcessList.FOREGROUND_APP_ADJ;
16176            schedGroup = (queue == mFgBroadcastQueue)
16177                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16178            app.adjType = "broadcast";
16179            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16180        } else if (app.executingServices.size() > 0) {
16181            // An app that is currently executing a service callback also
16182            // counts as being in the foreground.
16183            adj = ProcessList.FOREGROUND_APP_ADJ;
16184            schedGroup = app.execServicesFg ?
16185                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16186            app.adjType = "exec-service";
16187            procState = ActivityManager.PROCESS_STATE_SERVICE;
16188            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16189        } else {
16190            // As far as we know the process is empty.  We may change our mind later.
16191            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16192            // At this point we don't actually know the adjustment.  Use the cached adj
16193            // value that the caller wants us to.
16194            adj = cachedAdj;
16195            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16196            app.cached = true;
16197            app.empty = true;
16198            app.adjType = "cch-empty";
16199        }
16200
16201        // Examine all activities if not already foreground.
16202        if (!foregroundActivities && activitiesSize > 0) {
16203            for (int j = 0; j < activitiesSize; j++) {
16204                final ActivityRecord r = app.activities.get(j);
16205                if (r.app != app) {
16206                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16207                            + app + "?!?");
16208                    continue;
16209                }
16210                if (r.visible) {
16211                    // App has a visible activity; only upgrade adjustment.
16212                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16213                        adj = ProcessList.VISIBLE_APP_ADJ;
16214                        app.adjType = "visible";
16215                    }
16216                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16217                        procState = ActivityManager.PROCESS_STATE_TOP;
16218                    }
16219                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16220                    app.cached = false;
16221                    app.empty = false;
16222                    foregroundActivities = true;
16223                    break;
16224                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16225                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16226                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16227                        app.adjType = "pausing";
16228                    }
16229                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16230                        procState = ActivityManager.PROCESS_STATE_TOP;
16231                    }
16232                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16233                    app.cached = false;
16234                    app.empty = false;
16235                    foregroundActivities = true;
16236                } else if (r.state == ActivityState.STOPPING) {
16237                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16238                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16239                        app.adjType = "stopping";
16240                    }
16241                    // For the process state, we will at this point consider the
16242                    // process to be cached.  It will be cached either as an activity
16243                    // or empty depending on whether the activity is finishing.  We do
16244                    // this so that we can treat the process as cached for purposes of
16245                    // memory trimming (determing current memory level, trim command to
16246                    // send to process) since there can be an arbitrary number of stopping
16247                    // processes and they should soon all go into the cached state.
16248                    if (!r.finishing) {
16249                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16250                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16251                        }
16252                    }
16253                    app.cached = false;
16254                    app.empty = false;
16255                    foregroundActivities = true;
16256                } else {
16257                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16258                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16259                        app.adjType = "cch-act";
16260                    }
16261                }
16262            }
16263        }
16264
16265        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16266            if (app.foregroundServices) {
16267                // The user is aware of this app, so make it visible.
16268                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16269                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16270                app.cached = false;
16271                app.adjType = "fg-service";
16272                schedGroup = Process.THREAD_GROUP_DEFAULT;
16273            } else if (app.forcingToForeground != null) {
16274                // The user is aware of this app, so make it visible.
16275                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16276                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16277                app.cached = false;
16278                app.adjType = "force-fg";
16279                app.adjSource = app.forcingToForeground;
16280                schedGroup = Process.THREAD_GROUP_DEFAULT;
16281            }
16282        }
16283
16284        if (app == mHeavyWeightProcess) {
16285            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16286                // We don't want to kill the current heavy-weight process.
16287                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16288                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16289                app.cached = false;
16290                app.adjType = "heavy";
16291            }
16292            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16293                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16294            }
16295        }
16296
16297        if (app == mHomeProcess) {
16298            if (adj > ProcessList.HOME_APP_ADJ) {
16299                // This process is hosting what we currently consider to be the
16300                // home app, so we don't want to let it go into the background.
16301                adj = ProcessList.HOME_APP_ADJ;
16302                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16303                app.cached = false;
16304                app.adjType = "home";
16305            }
16306            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16307                procState = ActivityManager.PROCESS_STATE_HOME;
16308            }
16309        }
16310
16311        if (app == mPreviousProcess && app.activities.size() > 0) {
16312            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16313                // This was the previous process that showed UI to the user.
16314                // We want to try to keep it around more aggressively, to give
16315                // a good experience around switching between two apps.
16316                adj = ProcessList.PREVIOUS_APP_ADJ;
16317                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16318                app.cached = false;
16319                app.adjType = "previous";
16320            }
16321            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16322                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16323            }
16324        }
16325
16326        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16327                + " reason=" + app.adjType);
16328
16329        // By default, we use the computed adjustment.  It may be changed if
16330        // there are applications dependent on our services or providers, but
16331        // this gives us a baseline and makes sure we don't get into an
16332        // infinite recursion.
16333        app.adjSeq = mAdjSeq;
16334        app.curRawAdj = adj;
16335        app.hasStartedServices = false;
16336
16337        if (mBackupTarget != null && app == mBackupTarget.app) {
16338            // If possible we want to avoid killing apps while they're being backed up
16339            if (adj > ProcessList.BACKUP_APP_ADJ) {
16340                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16341                adj = ProcessList.BACKUP_APP_ADJ;
16342                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16343                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16344                }
16345                app.adjType = "backup";
16346                app.cached = false;
16347            }
16348            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16349                procState = ActivityManager.PROCESS_STATE_BACKUP;
16350            }
16351        }
16352
16353        boolean mayBeTop = false;
16354
16355        for (int is = app.services.size()-1;
16356                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16357                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16358                        || procState > ActivityManager.PROCESS_STATE_TOP);
16359                is--) {
16360            ServiceRecord s = app.services.valueAt(is);
16361            if (s.startRequested) {
16362                app.hasStartedServices = true;
16363                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16364                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16365                }
16366                if (app.hasShownUi && app != mHomeProcess) {
16367                    // If this process has shown some UI, let it immediately
16368                    // go to the LRU list because it may be pretty heavy with
16369                    // UI stuff.  We'll tag it with a label just to help
16370                    // debug and understand what is going on.
16371                    if (adj > ProcessList.SERVICE_ADJ) {
16372                        app.adjType = "cch-started-ui-services";
16373                    }
16374                } else {
16375                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16376                        // This service has seen some activity within
16377                        // recent memory, so we will keep its process ahead
16378                        // of the background processes.
16379                        if (adj > ProcessList.SERVICE_ADJ) {
16380                            adj = ProcessList.SERVICE_ADJ;
16381                            app.adjType = "started-services";
16382                            app.cached = false;
16383                        }
16384                    }
16385                    // If we have let the service slide into the background
16386                    // state, still have some text describing what it is doing
16387                    // even though the service no longer has an impact.
16388                    if (adj > ProcessList.SERVICE_ADJ) {
16389                        app.adjType = "cch-started-services";
16390                    }
16391                }
16392            }
16393            for (int conni = s.connections.size()-1;
16394                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16395                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16396                            || procState > ActivityManager.PROCESS_STATE_TOP);
16397                    conni--) {
16398                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16399                for (int i = 0;
16400                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16401                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16402                                || procState > ActivityManager.PROCESS_STATE_TOP);
16403                        i++) {
16404                    // XXX should compute this based on the max of
16405                    // all connected clients.
16406                    ConnectionRecord cr = clist.get(i);
16407                    if (cr.binding.client == app) {
16408                        // Binding to ourself is not interesting.
16409                        continue;
16410                    }
16411                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16412                        ProcessRecord client = cr.binding.client;
16413                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16414                                TOP_APP, doingAll, now);
16415                        int clientProcState = client.curProcState;
16416                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16417                            // If the other app is cached for any reason, for purposes here
16418                            // we are going to consider it empty.  The specific cached state
16419                            // doesn't propagate except under certain conditions.
16420                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16421                        }
16422                        String adjType = null;
16423                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16424                            // Not doing bind OOM management, so treat
16425                            // this guy more like a started service.
16426                            if (app.hasShownUi && app != mHomeProcess) {
16427                                // If this process has shown some UI, let it immediately
16428                                // go to the LRU list because it may be pretty heavy with
16429                                // UI stuff.  We'll tag it with a label just to help
16430                                // debug and understand what is going on.
16431                                if (adj > clientAdj) {
16432                                    adjType = "cch-bound-ui-services";
16433                                }
16434                                app.cached = false;
16435                                clientAdj = adj;
16436                                clientProcState = procState;
16437                            } else {
16438                                if (now >= (s.lastActivity
16439                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16440                                    // This service has not seen activity within
16441                                    // recent memory, so allow it to drop to the
16442                                    // LRU list if there is no other reason to keep
16443                                    // it around.  We'll also tag it with a label just
16444                                    // to help debug and undertand what is going on.
16445                                    if (adj > clientAdj) {
16446                                        adjType = "cch-bound-services";
16447                                    }
16448                                    clientAdj = adj;
16449                                }
16450                            }
16451                        }
16452                        if (adj > clientAdj) {
16453                            // If this process has recently shown UI, and
16454                            // the process that is binding to it is less
16455                            // important than being visible, then we don't
16456                            // care about the binding as much as we care
16457                            // about letting this process get into the LRU
16458                            // list to be killed and restarted if needed for
16459                            // memory.
16460                            if (app.hasShownUi && app != mHomeProcess
16461                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16462                                adjType = "cch-bound-ui-services";
16463                            } else {
16464                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16465                                        |Context.BIND_IMPORTANT)) != 0) {
16466                                    adj = clientAdj;
16467                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16468                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16469                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16470                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16471                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16472                                    adj = clientAdj;
16473                                } else {
16474                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16475                                        adj = ProcessList.VISIBLE_APP_ADJ;
16476                                    }
16477                                }
16478                                if (!client.cached) {
16479                                    app.cached = false;
16480                                }
16481                                adjType = "service";
16482                            }
16483                        }
16484                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16485                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16486                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16487                            }
16488                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16489                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16490                                    // Special handling of clients who are in the top state.
16491                                    // We *may* want to consider this process to be in the
16492                                    // top state as well, but only if there is not another
16493                                    // reason for it to be running.  Being on the top is a
16494                                    // special state, meaning you are specifically running
16495                                    // for the current top app.  If the process is already
16496                                    // running in the background for some other reason, it
16497                                    // is more important to continue considering it to be
16498                                    // in the background state.
16499                                    mayBeTop = true;
16500                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16501                                } else {
16502                                    // Special handling for above-top states (persistent
16503                                    // processes).  These should not bring the current process
16504                                    // into the top state, since they are not on top.  Instead
16505                                    // give them the best state after that.
16506                                    clientProcState =
16507                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16508                                }
16509                            }
16510                        } else {
16511                            if (clientProcState <
16512                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16513                                clientProcState =
16514                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16515                            }
16516                        }
16517                        if (procState > clientProcState) {
16518                            procState = clientProcState;
16519                        }
16520                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16521                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16522                            app.pendingUiClean = true;
16523                        }
16524                        if (adjType != null) {
16525                            app.adjType = adjType;
16526                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16527                                    .REASON_SERVICE_IN_USE;
16528                            app.adjSource = cr.binding.client;
16529                            app.adjSourceProcState = clientProcState;
16530                            app.adjTarget = s.name;
16531                        }
16532                    }
16533                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16534                        app.treatLikeActivity = true;
16535                    }
16536                    final ActivityRecord a = cr.activity;
16537                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16538                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16539                                (a.visible || a.state == ActivityState.RESUMED
16540                                 || a.state == ActivityState.PAUSING)) {
16541                            adj = ProcessList.FOREGROUND_APP_ADJ;
16542                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16543                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16544                            }
16545                            app.cached = false;
16546                            app.adjType = "service";
16547                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16548                                    .REASON_SERVICE_IN_USE;
16549                            app.adjSource = a;
16550                            app.adjSourceProcState = procState;
16551                            app.adjTarget = s.name;
16552                        }
16553                    }
16554                }
16555            }
16556        }
16557
16558        for (int provi = app.pubProviders.size()-1;
16559                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16560                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16561                        || procState > ActivityManager.PROCESS_STATE_TOP);
16562                provi--) {
16563            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16564            for (int i = cpr.connections.size()-1;
16565                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16566                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16567                            || procState > ActivityManager.PROCESS_STATE_TOP);
16568                    i--) {
16569                ContentProviderConnection conn = cpr.connections.get(i);
16570                ProcessRecord client = conn.client;
16571                if (client == app) {
16572                    // Being our own client is not interesting.
16573                    continue;
16574                }
16575                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16576                int clientProcState = client.curProcState;
16577                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16578                    // If the other app is cached for any reason, for purposes here
16579                    // we are going to consider it empty.
16580                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16581                }
16582                if (adj > clientAdj) {
16583                    if (app.hasShownUi && app != mHomeProcess
16584                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16585                        app.adjType = "cch-ui-provider";
16586                    } else {
16587                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16588                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16589                        app.adjType = "provider";
16590                    }
16591                    app.cached &= client.cached;
16592                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16593                            .REASON_PROVIDER_IN_USE;
16594                    app.adjSource = client;
16595                    app.adjSourceProcState = clientProcState;
16596                    app.adjTarget = cpr.name;
16597                }
16598                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16599                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16600                        // Special handling of clients who are in the top state.
16601                        // We *may* want to consider this process to be in the
16602                        // top state as well, but only if there is not another
16603                        // reason for it to be running.  Being on the top is a
16604                        // special state, meaning you are specifically running
16605                        // for the current top app.  If the process is already
16606                        // running in the background for some other reason, it
16607                        // is more important to continue considering it to be
16608                        // in the background state.
16609                        mayBeTop = true;
16610                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16611                    } else {
16612                        // Special handling for above-top states (persistent
16613                        // processes).  These should not bring the current process
16614                        // into the top state, since they are not on top.  Instead
16615                        // give them the best state after that.
16616                        clientProcState =
16617                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16618                    }
16619                }
16620                if (procState > clientProcState) {
16621                    procState = clientProcState;
16622                }
16623                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16624                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16625                }
16626            }
16627            // If the provider has external (non-framework) process
16628            // dependencies, ensure that its adjustment is at least
16629            // FOREGROUND_APP_ADJ.
16630            if (cpr.hasExternalProcessHandles()) {
16631                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16632                    adj = ProcessList.FOREGROUND_APP_ADJ;
16633                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16634                    app.cached = false;
16635                    app.adjType = "provider";
16636                    app.adjTarget = cpr.name;
16637                }
16638                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16639                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16640                }
16641            }
16642        }
16643
16644        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16645            // A client of one of our services or providers is in the top state.  We
16646            // *may* want to be in the top state, but not if we are already running in
16647            // the background for some other reason.  For the decision here, we are going
16648            // to pick out a few specific states that we want to remain in when a client
16649            // is top (states that tend to be longer-term) and otherwise allow it to go
16650            // to the top state.
16651            switch (procState) {
16652                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16653                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16654                case ActivityManager.PROCESS_STATE_SERVICE:
16655                    // These all are longer-term states, so pull them up to the top
16656                    // of the background states, but not all the way to the top state.
16657                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16658                    break;
16659                default:
16660                    // Otherwise, top is a better choice, so take it.
16661                    procState = ActivityManager.PROCESS_STATE_TOP;
16662                    break;
16663            }
16664        }
16665
16666        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16667            if (app.hasClientActivities) {
16668                // This is a cached process, but with client activities.  Mark it so.
16669                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16670                app.adjType = "cch-client-act";
16671            } else if (app.treatLikeActivity) {
16672                // This is a cached process, but somebody wants us to treat it like it has
16673                // an activity, okay!
16674                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16675                app.adjType = "cch-as-act";
16676            }
16677        }
16678
16679        if (adj == ProcessList.SERVICE_ADJ) {
16680            if (doingAll) {
16681                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16682                mNewNumServiceProcs++;
16683                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16684                if (!app.serviceb) {
16685                    // This service isn't far enough down on the LRU list to
16686                    // normally be a B service, but if we are low on RAM and it
16687                    // is large we want to force it down since we would prefer to
16688                    // keep launcher over it.
16689                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16690                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16691                        app.serviceHighRam = true;
16692                        app.serviceb = true;
16693                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16694                    } else {
16695                        mNewNumAServiceProcs++;
16696                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16697                    }
16698                } else {
16699                    app.serviceHighRam = false;
16700                }
16701            }
16702            if (app.serviceb) {
16703                adj = ProcessList.SERVICE_B_ADJ;
16704            }
16705        }
16706
16707        app.curRawAdj = adj;
16708
16709        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16710        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16711        if (adj > app.maxAdj) {
16712            adj = app.maxAdj;
16713            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16714                schedGroup = Process.THREAD_GROUP_DEFAULT;
16715            }
16716        }
16717
16718        // Do final modification to adj.  Everything we do between here and applying
16719        // the final setAdj must be done in this function, because we will also use
16720        // it when computing the final cached adj later.  Note that we don't need to
16721        // worry about this for max adj above, since max adj will always be used to
16722        // keep it out of the cached vaues.
16723        app.curAdj = app.modifyRawOomAdj(adj);
16724        app.curSchedGroup = schedGroup;
16725        app.curProcState = procState;
16726        app.foregroundActivities = foregroundActivities;
16727
16728        return app.curRawAdj;
16729    }
16730
16731    /**
16732     * Schedule PSS collection of a process.
16733     */
16734    void requestPssLocked(ProcessRecord proc, int procState) {
16735        if (mPendingPssProcesses.contains(proc)) {
16736            return;
16737        }
16738        if (mPendingPssProcesses.size() == 0) {
16739            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16740        }
16741        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16742        proc.pssProcState = procState;
16743        mPendingPssProcesses.add(proc);
16744    }
16745
16746    /**
16747     * Schedule PSS collection of all processes.
16748     */
16749    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16750        if (!always) {
16751            if (now < (mLastFullPssTime +
16752                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16753                return;
16754            }
16755        }
16756        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16757        mLastFullPssTime = now;
16758        mFullPssPending = true;
16759        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16760        mPendingPssProcesses.clear();
16761        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16762            ProcessRecord app = mLruProcesses.get(i);
16763            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16764                app.pssProcState = app.setProcState;
16765                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16766                        isSleeping(), now);
16767                mPendingPssProcesses.add(app);
16768            }
16769        }
16770        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16771    }
16772
16773    /**
16774     * Ask a given process to GC right now.
16775     */
16776    final void performAppGcLocked(ProcessRecord app) {
16777        try {
16778            app.lastRequestedGc = SystemClock.uptimeMillis();
16779            if (app.thread != null) {
16780                if (app.reportLowMemory) {
16781                    app.reportLowMemory = false;
16782                    app.thread.scheduleLowMemory();
16783                } else {
16784                    app.thread.processInBackground();
16785                }
16786            }
16787        } catch (Exception e) {
16788            // whatever.
16789        }
16790    }
16791
16792    /**
16793     * Returns true if things are idle enough to perform GCs.
16794     */
16795    private final boolean canGcNowLocked() {
16796        boolean processingBroadcasts = false;
16797        for (BroadcastQueue q : mBroadcastQueues) {
16798            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16799                processingBroadcasts = true;
16800            }
16801        }
16802        return !processingBroadcasts
16803                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16804    }
16805
16806    /**
16807     * Perform GCs on all processes that are waiting for it, but only
16808     * if things are idle.
16809     */
16810    final void performAppGcsLocked() {
16811        final int N = mProcessesToGc.size();
16812        if (N <= 0) {
16813            return;
16814        }
16815        if (canGcNowLocked()) {
16816            while (mProcessesToGc.size() > 0) {
16817                ProcessRecord proc = mProcessesToGc.remove(0);
16818                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16819                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16820                            <= SystemClock.uptimeMillis()) {
16821                        // To avoid spamming the system, we will GC processes one
16822                        // at a time, waiting a few seconds between each.
16823                        performAppGcLocked(proc);
16824                        scheduleAppGcsLocked();
16825                        return;
16826                    } else {
16827                        // It hasn't been long enough since we last GCed this
16828                        // process...  put it in the list to wait for its time.
16829                        addProcessToGcListLocked(proc);
16830                        break;
16831                    }
16832                }
16833            }
16834
16835            scheduleAppGcsLocked();
16836        }
16837    }
16838
16839    /**
16840     * If all looks good, perform GCs on all processes waiting for them.
16841     */
16842    final void performAppGcsIfAppropriateLocked() {
16843        if (canGcNowLocked()) {
16844            performAppGcsLocked();
16845            return;
16846        }
16847        // Still not idle, wait some more.
16848        scheduleAppGcsLocked();
16849    }
16850
16851    /**
16852     * Schedule the execution of all pending app GCs.
16853     */
16854    final void scheduleAppGcsLocked() {
16855        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16856
16857        if (mProcessesToGc.size() > 0) {
16858            // Schedule a GC for the time to the next process.
16859            ProcessRecord proc = mProcessesToGc.get(0);
16860            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16861
16862            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16863            long now = SystemClock.uptimeMillis();
16864            if (when < (now+GC_TIMEOUT)) {
16865                when = now + GC_TIMEOUT;
16866            }
16867            mHandler.sendMessageAtTime(msg, when);
16868        }
16869    }
16870
16871    /**
16872     * Add a process to the array of processes waiting to be GCed.  Keeps the
16873     * list in sorted order by the last GC time.  The process can't already be
16874     * on the list.
16875     */
16876    final void addProcessToGcListLocked(ProcessRecord proc) {
16877        boolean added = false;
16878        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16879            if (mProcessesToGc.get(i).lastRequestedGc <
16880                    proc.lastRequestedGc) {
16881                added = true;
16882                mProcessesToGc.add(i+1, proc);
16883                break;
16884            }
16885        }
16886        if (!added) {
16887            mProcessesToGc.add(0, proc);
16888        }
16889    }
16890
16891    /**
16892     * Set up to ask a process to GC itself.  This will either do it
16893     * immediately, or put it on the list of processes to gc the next
16894     * time things are idle.
16895     */
16896    final void scheduleAppGcLocked(ProcessRecord app) {
16897        long now = SystemClock.uptimeMillis();
16898        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16899            return;
16900        }
16901        if (!mProcessesToGc.contains(app)) {
16902            addProcessToGcListLocked(app);
16903            scheduleAppGcsLocked();
16904        }
16905    }
16906
16907    final void checkExcessivePowerUsageLocked(boolean doKills) {
16908        updateCpuStatsNow();
16909
16910        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16911        boolean doWakeKills = doKills;
16912        boolean doCpuKills = doKills;
16913        if (mLastPowerCheckRealtime == 0) {
16914            doWakeKills = false;
16915        }
16916        if (mLastPowerCheckUptime == 0) {
16917            doCpuKills = false;
16918        }
16919        if (stats.isScreenOn()) {
16920            doWakeKills = false;
16921        }
16922        final long curRealtime = SystemClock.elapsedRealtime();
16923        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16924        final long curUptime = SystemClock.uptimeMillis();
16925        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16926        mLastPowerCheckRealtime = curRealtime;
16927        mLastPowerCheckUptime = curUptime;
16928        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16929            doWakeKills = false;
16930        }
16931        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16932            doCpuKills = false;
16933        }
16934        int i = mLruProcesses.size();
16935        while (i > 0) {
16936            i--;
16937            ProcessRecord app = mLruProcesses.get(i);
16938            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16939                long wtime;
16940                synchronized (stats) {
16941                    wtime = stats.getProcessWakeTime(app.info.uid,
16942                            app.pid, curRealtime);
16943                }
16944                long wtimeUsed = wtime - app.lastWakeTime;
16945                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16946                if (DEBUG_POWER) {
16947                    StringBuilder sb = new StringBuilder(128);
16948                    sb.append("Wake for ");
16949                    app.toShortString(sb);
16950                    sb.append(": over ");
16951                    TimeUtils.formatDuration(realtimeSince, sb);
16952                    sb.append(" used ");
16953                    TimeUtils.formatDuration(wtimeUsed, sb);
16954                    sb.append(" (");
16955                    sb.append((wtimeUsed*100)/realtimeSince);
16956                    sb.append("%)");
16957                    Slog.i(TAG, sb.toString());
16958                    sb.setLength(0);
16959                    sb.append("CPU for ");
16960                    app.toShortString(sb);
16961                    sb.append(": over ");
16962                    TimeUtils.formatDuration(uptimeSince, sb);
16963                    sb.append(" used ");
16964                    TimeUtils.formatDuration(cputimeUsed, sb);
16965                    sb.append(" (");
16966                    sb.append((cputimeUsed*100)/uptimeSince);
16967                    sb.append("%)");
16968                    Slog.i(TAG, sb.toString());
16969                }
16970                // If a process has held a wake lock for more
16971                // than 50% of the time during this period,
16972                // that sounds bad.  Kill!
16973                if (doWakeKills && realtimeSince > 0
16974                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16975                    synchronized (stats) {
16976                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16977                                realtimeSince, wtimeUsed);
16978                    }
16979                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16980                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16981                } else if (doCpuKills && uptimeSince > 0
16982                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16983                    synchronized (stats) {
16984                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16985                                uptimeSince, cputimeUsed);
16986                    }
16987                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16988                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16989                } else {
16990                    app.lastWakeTime = wtime;
16991                    app.lastCpuTime = app.curCpuTime;
16992                }
16993            }
16994        }
16995    }
16996
16997    private final boolean applyOomAdjLocked(ProcessRecord app,
16998            ProcessRecord TOP_APP, boolean doingAll, long now) {
16999        boolean success = true;
17000
17001        if (app.curRawAdj != app.setRawAdj) {
17002            app.setRawAdj = app.curRawAdj;
17003        }
17004
17005        int changes = 0;
17006
17007        if (app.curAdj != app.setAdj) {
17008            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17009            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17010                TAG, "Set " + app.pid + " " + app.processName +
17011                " adj " + app.curAdj + ": " + app.adjType);
17012            app.setAdj = app.curAdj;
17013        }
17014
17015        if (app.setSchedGroup != app.curSchedGroup) {
17016            app.setSchedGroup = app.curSchedGroup;
17017            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17018                    "Setting process group of " + app.processName
17019                    + " to " + app.curSchedGroup);
17020            if (app.waitingToKill != null &&
17021                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17022                app.kill(app.waitingToKill, true);
17023                success = false;
17024            } else {
17025                if (true) {
17026                    long oldId = Binder.clearCallingIdentity();
17027                    try {
17028                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17029                    } catch (Exception e) {
17030                        Slog.w(TAG, "Failed setting process group of " + app.pid
17031                                + " to " + app.curSchedGroup);
17032                        e.printStackTrace();
17033                    } finally {
17034                        Binder.restoreCallingIdentity(oldId);
17035                    }
17036                } else {
17037                    if (app.thread != null) {
17038                        try {
17039                            app.thread.setSchedulingGroup(app.curSchedGroup);
17040                        } catch (RemoteException e) {
17041                        }
17042                    }
17043                }
17044                Process.setSwappiness(app.pid,
17045                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17046            }
17047        }
17048        if (app.repForegroundActivities != app.foregroundActivities) {
17049            app.repForegroundActivities = app.foregroundActivities;
17050            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17051        }
17052        if (app.repProcState != app.curProcState) {
17053            app.repProcState = app.curProcState;
17054            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17055            if (app.thread != null) {
17056                try {
17057                    if (false) {
17058                        //RuntimeException h = new RuntimeException("here");
17059                        Slog.i(TAG, "Sending new process state " + app.repProcState
17060                                + " to " + app /*, h*/);
17061                    }
17062                    app.thread.setProcessState(app.repProcState);
17063                } catch (RemoteException e) {
17064                }
17065            }
17066        }
17067        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17068                app.setProcState)) {
17069            app.lastStateTime = now;
17070            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17071                    isSleeping(), now);
17072            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17073                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17074                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17075                    + (app.nextPssTime-now) + ": " + app);
17076        } else {
17077            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17078                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17079                requestPssLocked(app, app.setProcState);
17080                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17081                        isSleeping(), now);
17082            } else if (false && DEBUG_PSS) {
17083                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17084            }
17085        }
17086        if (app.setProcState != app.curProcState) {
17087            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17088                    "Proc state change of " + app.processName
17089                    + " to " + app.curProcState);
17090            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17091            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17092            if (setImportant && !curImportant) {
17093                // This app is no longer something we consider important enough to allow to
17094                // use arbitrary amounts of battery power.  Note
17095                // its current wake lock time to later know to kill it if
17096                // it is not behaving well.
17097                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17098                synchronized (stats) {
17099                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17100                            app.pid, SystemClock.elapsedRealtime());
17101                }
17102                app.lastCpuTime = app.curCpuTime;
17103
17104            }
17105            app.setProcState = app.curProcState;
17106            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17107                app.notCachedSinceIdle = false;
17108            }
17109            if (!doingAll) {
17110                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17111            } else {
17112                app.procStateChanged = true;
17113            }
17114        }
17115
17116        if (changes != 0) {
17117            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17118            int i = mPendingProcessChanges.size()-1;
17119            ProcessChangeItem item = null;
17120            while (i >= 0) {
17121                item = mPendingProcessChanges.get(i);
17122                if (item.pid == app.pid) {
17123                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17124                    break;
17125                }
17126                i--;
17127            }
17128            if (i < 0) {
17129                // No existing item in pending changes; need a new one.
17130                final int NA = mAvailProcessChanges.size();
17131                if (NA > 0) {
17132                    item = mAvailProcessChanges.remove(NA-1);
17133                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17134                } else {
17135                    item = new ProcessChangeItem();
17136                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17137                }
17138                item.changes = 0;
17139                item.pid = app.pid;
17140                item.uid = app.info.uid;
17141                if (mPendingProcessChanges.size() == 0) {
17142                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17143                            "*** Enqueueing dispatch processes changed!");
17144                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17145                }
17146                mPendingProcessChanges.add(item);
17147            }
17148            item.changes |= changes;
17149            item.processState = app.repProcState;
17150            item.foregroundActivities = app.repForegroundActivities;
17151            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17152                    + Integer.toHexString(System.identityHashCode(item))
17153                    + " " + app.toShortString() + ": changes=" + item.changes
17154                    + " procState=" + item.processState
17155                    + " foreground=" + item.foregroundActivities
17156                    + " type=" + app.adjType + " source=" + app.adjSource
17157                    + " target=" + app.adjTarget);
17158        }
17159
17160        return success;
17161    }
17162
17163    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17164        if (proc.thread != null) {
17165            if (proc.baseProcessTracker != null) {
17166                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17167            }
17168            if (proc.repProcState >= 0) {
17169                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17170                        proc.repProcState);
17171            }
17172        }
17173    }
17174
17175    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17176            ProcessRecord TOP_APP, boolean doingAll, long now) {
17177        if (app.thread == null) {
17178            return false;
17179        }
17180
17181        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17182
17183        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17184    }
17185
17186    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17187            boolean oomAdj) {
17188        if (isForeground != proc.foregroundServices) {
17189            proc.foregroundServices = isForeground;
17190            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17191                    proc.info.uid);
17192            if (isForeground) {
17193                if (curProcs == null) {
17194                    curProcs = new ArrayList<ProcessRecord>();
17195                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17196                }
17197                if (!curProcs.contains(proc)) {
17198                    curProcs.add(proc);
17199                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17200                            proc.info.packageName, proc.info.uid);
17201                }
17202            } else {
17203                if (curProcs != null) {
17204                    if (curProcs.remove(proc)) {
17205                        mBatteryStatsService.noteEvent(
17206                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17207                                proc.info.packageName, proc.info.uid);
17208                        if (curProcs.size() <= 0) {
17209                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17210                        }
17211                    }
17212                }
17213            }
17214            if (oomAdj) {
17215                updateOomAdjLocked();
17216            }
17217        }
17218    }
17219
17220    private final ActivityRecord resumedAppLocked() {
17221        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17222        String pkg;
17223        int uid;
17224        if (act != null) {
17225            pkg = act.packageName;
17226            uid = act.info.applicationInfo.uid;
17227        } else {
17228            pkg = null;
17229            uid = -1;
17230        }
17231        // Has the UID or resumed package name changed?
17232        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17233                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17234            if (mCurResumedPackage != null) {
17235                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17236                        mCurResumedPackage, mCurResumedUid);
17237            }
17238            mCurResumedPackage = pkg;
17239            mCurResumedUid = uid;
17240            if (mCurResumedPackage != null) {
17241                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17242                        mCurResumedPackage, mCurResumedUid);
17243            }
17244        }
17245        return act;
17246    }
17247
17248    final boolean updateOomAdjLocked(ProcessRecord app) {
17249        final ActivityRecord TOP_ACT = resumedAppLocked();
17250        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17251        final boolean wasCached = app.cached;
17252
17253        mAdjSeq++;
17254
17255        // This is the desired cached adjusment we want to tell it to use.
17256        // If our app is currently cached, we know it, and that is it.  Otherwise,
17257        // we don't know it yet, and it needs to now be cached we will then
17258        // need to do a complete oom adj.
17259        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17260                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17261        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17262                SystemClock.uptimeMillis());
17263        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17264            // Changed to/from cached state, so apps after it in the LRU
17265            // list may also be changed.
17266            updateOomAdjLocked();
17267        }
17268        return success;
17269    }
17270
17271    final void updateOomAdjLocked() {
17272        final ActivityRecord TOP_ACT = resumedAppLocked();
17273        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17274        final long now = SystemClock.uptimeMillis();
17275        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17276        final int N = mLruProcesses.size();
17277
17278        if (false) {
17279            RuntimeException e = new RuntimeException();
17280            e.fillInStackTrace();
17281            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17282        }
17283
17284        mAdjSeq++;
17285        mNewNumServiceProcs = 0;
17286        mNewNumAServiceProcs = 0;
17287
17288        final int emptyProcessLimit;
17289        final int cachedProcessLimit;
17290        if (mProcessLimit <= 0) {
17291            emptyProcessLimit = cachedProcessLimit = 0;
17292        } else if (mProcessLimit == 1) {
17293            emptyProcessLimit = 1;
17294            cachedProcessLimit = 0;
17295        } else {
17296            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17297            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17298        }
17299
17300        // Let's determine how many processes we have running vs.
17301        // how many slots we have for background processes; we may want
17302        // to put multiple processes in a slot of there are enough of
17303        // them.
17304        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17305                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17306        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17307        if (numEmptyProcs > cachedProcessLimit) {
17308            // If there are more empty processes than our limit on cached
17309            // processes, then use the cached process limit for the factor.
17310            // This ensures that the really old empty processes get pushed
17311            // down to the bottom, so if we are running low on memory we will
17312            // have a better chance at keeping around more cached processes
17313            // instead of a gazillion empty processes.
17314            numEmptyProcs = cachedProcessLimit;
17315        }
17316        int emptyFactor = numEmptyProcs/numSlots;
17317        if (emptyFactor < 1) emptyFactor = 1;
17318        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17319        if (cachedFactor < 1) cachedFactor = 1;
17320        int stepCached = 0;
17321        int stepEmpty = 0;
17322        int numCached = 0;
17323        int numEmpty = 0;
17324        int numTrimming = 0;
17325
17326        mNumNonCachedProcs = 0;
17327        mNumCachedHiddenProcs = 0;
17328
17329        // First update the OOM adjustment for each of the
17330        // application processes based on their current state.
17331        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17332        int nextCachedAdj = curCachedAdj+1;
17333        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17334        int nextEmptyAdj = curEmptyAdj+2;
17335        for (int i=N-1; i>=0; i--) {
17336            ProcessRecord app = mLruProcesses.get(i);
17337            if (!app.killedByAm && app.thread != null) {
17338                app.procStateChanged = false;
17339                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17340
17341                // If we haven't yet assigned the final cached adj
17342                // to the process, do that now.
17343                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17344                    switch (app.curProcState) {
17345                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17346                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17347                            // This process is a cached process holding activities...
17348                            // assign it the next cached value for that type, and then
17349                            // step that cached level.
17350                            app.curRawAdj = curCachedAdj;
17351                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17352                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17353                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17354                                    + ")");
17355                            if (curCachedAdj != nextCachedAdj) {
17356                                stepCached++;
17357                                if (stepCached >= cachedFactor) {
17358                                    stepCached = 0;
17359                                    curCachedAdj = nextCachedAdj;
17360                                    nextCachedAdj += 2;
17361                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17362                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17363                                    }
17364                                }
17365                            }
17366                            break;
17367                        default:
17368                            // For everything else, assign next empty cached process
17369                            // level and bump that up.  Note that this means that
17370                            // long-running services that have dropped down to the
17371                            // cached level will be treated as empty (since their process
17372                            // state is still as a service), which is what we want.
17373                            app.curRawAdj = curEmptyAdj;
17374                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17375                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17376                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17377                                    + ")");
17378                            if (curEmptyAdj != nextEmptyAdj) {
17379                                stepEmpty++;
17380                                if (stepEmpty >= emptyFactor) {
17381                                    stepEmpty = 0;
17382                                    curEmptyAdj = nextEmptyAdj;
17383                                    nextEmptyAdj += 2;
17384                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17385                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17386                                    }
17387                                }
17388                            }
17389                            break;
17390                    }
17391                }
17392
17393                applyOomAdjLocked(app, TOP_APP, true, now);
17394
17395                // Count the number of process types.
17396                switch (app.curProcState) {
17397                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17398                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17399                        mNumCachedHiddenProcs++;
17400                        numCached++;
17401                        if (numCached > cachedProcessLimit) {
17402                            app.kill("cached #" + numCached, true);
17403                        }
17404                        break;
17405                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17406                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17407                                && app.lastActivityTime < oldTime) {
17408                            app.kill("empty for "
17409                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17410                                    / 1000) + "s", true);
17411                        } else {
17412                            numEmpty++;
17413                            if (numEmpty > emptyProcessLimit) {
17414                                app.kill("empty #" + numEmpty, true);
17415                            }
17416                        }
17417                        break;
17418                    default:
17419                        mNumNonCachedProcs++;
17420                        break;
17421                }
17422
17423                if (app.isolated && app.services.size() <= 0) {
17424                    // If this is an isolated process, and there are no
17425                    // services running in it, then the process is no longer
17426                    // needed.  We agressively kill these because we can by
17427                    // definition not re-use the same process again, and it is
17428                    // good to avoid having whatever code was running in them
17429                    // left sitting around after no longer needed.
17430                    app.kill("isolated not needed", true);
17431                }
17432
17433                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17434                        && !app.killedByAm) {
17435                    numTrimming++;
17436                }
17437            }
17438        }
17439
17440        mNumServiceProcs = mNewNumServiceProcs;
17441
17442        // Now determine the memory trimming level of background processes.
17443        // Unfortunately we need to start at the back of the list to do this
17444        // properly.  We only do this if the number of background apps we
17445        // are managing to keep around is less than half the maximum we desire;
17446        // if we are keeping a good number around, we'll let them use whatever
17447        // memory they want.
17448        final int numCachedAndEmpty = numCached + numEmpty;
17449        int memFactor;
17450        if (numCached <= ProcessList.TRIM_CACHED_APPS
17451                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17452            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17453                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17454            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17455                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17456            } else {
17457                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17458            }
17459        } else {
17460            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17461        }
17462        // We always allow the memory level to go up (better).  We only allow it to go
17463        // down if we are in a state where that is allowed, *and* the total number of processes
17464        // has gone down since last time.
17465        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17466                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17467                + " last=" + mLastNumProcesses);
17468        if (memFactor > mLastMemoryLevel) {
17469            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17470                memFactor = mLastMemoryLevel;
17471                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17472            }
17473        }
17474        mLastMemoryLevel = memFactor;
17475        mLastNumProcesses = mLruProcesses.size();
17476        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17477        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17478        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17479            if (mLowRamStartTime == 0) {
17480                mLowRamStartTime = now;
17481            }
17482            int step = 0;
17483            int fgTrimLevel;
17484            switch (memFactor) {
17485                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17486                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17487                    break;
17488                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17489                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17490                    break;
17491                default:
17492                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17493                    break;
17494            }
17495            int factor = numTrimming/3;
17496            int minFactor = 2;
17497            if (mHomeProcess != null) minFactor++;
17498            if (mPreviousProcess != null) minFactor++;
17499            if (factor < minFactor) factor = minFactor;
17500            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17501            for (int i=N-1; i>=0; i--) {
17502                ProcessRecord app = mLruProcesses.get(i);
17503                if (allChanged || app.procStateChanged) {
17504                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17505                    app.procStateChanged = false;
17506                }
17507                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17508                        && !app.killedByAm) {
17509                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17510                        try {
17511                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17512                                    "Trimming memory of " + app.processName
17513                                    + " to " + curLevel);
17514                            app.thread.scheduleTrimMemory(curLevel);
17515                        } catch (RemoteException e) {
17516                        }
17517                        if (false) {
17518                            // For now we won't do this; our memory trimming seems
17519                            // to be good enough at this point that destroying
17520                            // activities causes more harm than good.
17521                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17522                                    && app != mHomeProcess && app != mPreviousProcess) {
17523                                // Need to do this on its own message because the stack may not
17524                                // be in a consistent state at this point.
17525                                // For these apps we will also finish their activities
17526                                // to help them free memory.
17527                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17528                            }
17529                        }
17530                    }
17531                    app.trimMemoryLevel = curLevel;
17532                    step++;
17533                    if (step >= factor) {
17534                        step = 0;
17535                        switch (curLevel) {
17536                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17537                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17538                                break;
17539                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17540                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17541                                break;
17542                        }
17543                    }
17544                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17545                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17546                            && app.thread != null) {
17547                        try {
17548                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17549                                    "Trimming memory of heavy-weight " + app.processName
17550                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17551                            app.thread.scheduleTrimMemory(
17552                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17553                        } catch (RemoteException e) {
17554                        }
17555                    }
17556                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17557                } else {
17558                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17559                            || app.systemNoUi) && app.pendingUiClean) {
17560                        // If this application is now in the background and it
17561                        // had done UI, then give it the special trim level to
17562                        // have it free UI resources.
17563                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17564                        if (app.trimMemoryLevel < level && app.thread != null) {
17565                            try {
17566                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17567                                        "Trimming memory of bg-ui " + app.processName
17568                                        + " to " + level);
17569                                app.thread.scheduleTrimMemory(level);
17570                            } catch (RemoteException e) {
17571                            }
17572                        }
17573                        app.pendingUiClean = false;
17574                    }
17575                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17576                        try {
17577                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17578                                    "Trimming memory of fg " + app.processName
17579                                    + " to " + fgTrimLevel);
17580                            app.thread.scheduleTrimMemory(fgTrimLevel);
17581                        } catch (RemoteException e) {
17582                        }
17583                    }
17584                    app.trimMemoryLevel = fgTrimLevel;
17585                }
17586            }
17587        } else {
17588            if (mLowRamStartTime != 0) {
17589                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17590                mLowRamStartTime = 0;
17591            }
17592            for (int i=N-1; i>=0; i--) {
17593                ProcessRecord app = mLruProcesses.get(i);
17594                if (allChanged || app.procStateChanged) {
17595                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17596                    app.procStateChanged = false;
17597                }
17598                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17599                        || app.systemNoUi) && app.pendingUiClean) {
17600                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17601                            && app.thread != null) {
17602                        try {
17603                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17604                                    "Trimming memory of ui hidden " + app.processName
17605                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17606                            app.thread.scheduleTrimMemory(
17607                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17608                        } catch (RemoteException e) {
17609                        }
17610                    }
17611                    app.pendingUiClean = false;
17612                }
17613                app.trimMemoryLevel = 0;
17614            }
17615        }
17616
17617        if (mAlwaysFinishActivities) {
17618            // Need to do this on its own message because the stack may not
17619            // be in a consistent state at this point.
17620            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17621        }
17622
17623        if (allChanged) {
17624            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17625        }
17626
17627        if (mProcessStats.shouldWriteNowLocked(now)) {
17628            mHandler.post(new Runnable() {
17629                @Override public void run() {
17630                    synchronized (ActivityManagerService.this) {
17631                        mProcessStats.writeStateAsyncLocked();
17632                    }
17633                }
17634            });
17635        }
17636
17637        if (DEBUG_OOM_ADJ) {
17638            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17639        }
17640    }
17641
17642    final void trimApplications() {
17643        synchronized (this) {
17644            int i;
17645
17646            // First remove any unused application processes whose package
17647            // has been removed.
17648            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17649                final ProcessRecord app = mRemovedProcesses.get(i);
17650                if (app.activities.size() == 0
17651                        && app.curReceiver == null && app.services.size() == 0) {
17652                    Slog.i(
17653                        TAG, "Exiting empty application process "
17654                        + app.processName + " ("
17655                        + (app.thread != null ? app.thread.asBinder() : null)
17656                        + ")\n");
17657                    if (app.pid > 0 && app.pid != MY_PID) {
17658                        app.kill("empty", false);
17659                    } else {
17660                        try {
17661                            app.thread.scheduleExit();
17662                        } catch (Exception e) {
17663                            // Ignore exceptions.
17664                        }
17665                    }
17666                    cleanUpApplicationRecordLocked(app, false, true, -1);
17667                    mRemovedProcesses.remove(i);
17668
17669                    if (app.persistent) {
17670                        addAppLocked(app.info, false, null /* ABI override */);
17671                    }
17672                }
17673            }
17674
17675            // Now update the oom adj for all processes.
17676            updateOomAdjLocked();
17677        }
17678    }
17679
17680    /** This method sends the specified signal to each of the persistent apps */
17681    public void signalPersistentProcesses(int sig) throws RemoteException {
17682        if (sig != Process.SIGNAL_USR1) {
17683            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17684        }
17685
17686        synchronized (this) {
17687            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17688                    != PackageManager.PERMISSION_GRANTED) {
17689                throw new SecurityException("Requires permission "
17690                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17691            }
17692
17693            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17694                ProcessRecord r = mLruProcesses.get(i);
17695                if (r.thread != null && r.persistent) {
17696                    Process.sendSignal(r.pid, sig);
17697                }
17698            }
17699        }
17700    }
17701
17702    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17703        if (proc == null || proc == mProfileProc) {
17704            proc = mProfileProc;
17705            profileType = mProfileType;
17706            clearProfilerLocked();
17707        }
17708        if (proc == null) {
17709            return;
17710        }
17711        try {
17712            proc.thread.profilerControl(false, null, profileType);
17713        } catch (RemoteException e) {
17714            throw new IllegalStateException("Process disappeared");
17715        }
17716    }
17717
17718    private void clearProfilerLocked() {
17719        if (mProfileFd != null) {
17720            try {
17721                mProfileFd.close();
17722            } catch (IOException e) {
17723            }
17724        }
17725        mProfileApp = null;
17726        mProfileProc = null;
17727        mProfileFile = null;
17728        mProfileType = 0;
17729        mAutoStopProfiler = false;
17730        mSamplingInterval = 0;
17731    }
17732
17733    public boolean profileControl(String process, int userId, boolean start,
17734            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17735
17736        try {
17737            synchronized (this) {
17738                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17739                // its own permission.
17740                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17741                        != PackageManager.PERMISSION_GRANTED) {
17742                    throw new SecurityException("Requires permission "
17743                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17744                }
17745
17746                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17747                    throw new IllegalArgumentException("null profile info or fd");
17748                }
17749
17750                ProcessRecord proc = null;
17751                if (process != null) {
17752                    proc = findProcessLocked(process, userId, "profileControl");
17753                }
17754
17755                if (start && (proc == null || proc.thread == null)) {
17756                    throw new IllegalArgumentException("Unknown process: " + process);
17757                }
17758
17759                if (start) {
17760                    stopProfilerLocked(null, 0);
17761                    setProfileApp(proc.info, proc.processName, profilerInfo);
17762                    mProfileProc = proc;
17763                    mProfileType = profileType;
17764                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17765                    try {
17766                        fd = fd.dup();
17767                    } catch (IOException e) {
17768                        fd = null;
17769                    }
17770                    profilerInfo.profileFd = fd;
17771                    proc.thread.profilerControl(start, profilerInfo, profileType);
17772                    fd = null;
17773                    mProfileFd = null;
17774                } else {
17775                    stopProfilerLocked(proc, profileType);
17776                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17777                        try {
17778                            profilerInfo.profileFd.close();
17779                        } catch (IOException e) {
17780                        }
17781                    }
17782                }
17783
17784                return true;
17785            }
17786        } catch (RemoteException e) {
17787            throw new IllegalStateException("Process disappeared");
17788        } finally {
17789            if (profilerInfo != null && profilerInfo.profileFd != null) {
17790                try {
17791                    profilerInfo.profileFd.close();
17792                } catch (IOException e) {
17793                }
17794            }
17795        }
17796    }
17797
17798    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17799        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17800                userId, true, ALLOW_FULL_ONLY, callName, null);
17801        ProcessRecord proc = null;
17802        try {
17803            int pid = Integer.parseInt(process);
17804            synchronized (mPidsSelfLocked) {
17805                proc = mPidsSelfLocked.get(pid);
17806            }
17807        } catch (NumberFormatException e) {
17808        }
17809
17810        if (proc == null) {
17811            ArrayMap<String, SparseArray<ProcessRecord>> all
17812                    = mProcessNames.getMap();
17813            SparseArray<ProcessRecord> procs = all.get(process);
17814            if (procs != null && procs.size() > 0) {
17815                proc = procs.valueAt(0);
17816                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17817                    for (int i=1; i<procs.size(); i++) {
17818                        ProcessRecord thisProc = procs.valueAt(i);
17819                        if (thisProc.userId == userId) {
17820                            proc = thisProc;
17821                            break;
17822                        }
17823                    }
17824                }
17825            }
17826        }
17827
17828        return proc;
17829    }
17830
17831    public boolean dumpHeap(String process, int userId, boolean managed,
17832            String path, ParcelFileDescriptor fd) throws RemoteException {
17833
17834        try {
17835            synchronized (this) {
17836                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17837                // its own permission (same as profileControl).
17838                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17839                        != PackageManager.PERMISSION_GRANTED) {
17840                    throw new SecurityException("Requires permission "
17841                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17842                }
17843
17844                if (fd == null) {
17845                    throw new IllegalArgumentException("null fd");
17846                }
17847
17848                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17849                if (proc == null || proc.thread == null) {
17850                    throw new IllegalArgumentException("Unknown process: " + process);
17851                }
17852
17853                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17854                if (!isDebuggable) {
17855                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17856                        throw new SecurityException("Process not debuggable: " + proc);
17857                    }
17858                }
17859
17860                proc.thread.dumpHeap(managed, path, fd);
17861                fd = null;
17862                return true;
17863            }
17864        } catch (RemoteException e) {
17865            throw new IllegalStateException("Process disappeared");
17866        } finally {
17867            if (fd != null) {
17868                try {
17869                    fd.close();
17870                } catch (IOException e) {
17871                }
17872            }
17873        }
17874    }
17875
17876    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17877    public void monitor() {
17878        synchronized (this) { }
17879    }
17880
17881    void onCoreSettingsChange(Bundle settings) {
17882        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17883            ProcessRecord processRecord = mLruProcesses.get(i);
17884            try {
17885                if (processRecord.thread != null) {
17886                    processRecord.thread.setCoreSettings(settings);
17887                }
17888            } catch (RemoteException re) {
17889                /* ignore */
17890            }
17891        }
17892    }
17893
17894    // Multi-user methods
17895
17896    /**
17897     * Start user, if its not already running, but don't bring it to foreground.
17898     */
17899    @Override
17900    public boolean startUserInBackground(final int userId) {
17901        return startUser(userId, /* foreground */ false);
17902    }
17903
17904    /**
17905     * Start user, if its not already running, and bring it to foreground.
17906     */
17907    boolean startUserInForeground(final int userId, Dialog dlg) {
17908        boolean result = startUser(userId, /* foreground */ true);
17909        dlg.dismiss();
17910        return result;
17911    }
17912
17913    /**
17914     * Refreshes the list of users related to the current user when either a
17915     * user switch happens or when a new related user is started in the
17916     * background.
17917     */
17918    private void updateCurrentProfileIdsLocked() {
17919        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17920                mCurrentUserId, false /* enabledOnly */);
17921        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17922        for (int i = 0; i < currentProfileIds.length; i++) {
17923            currentProfileIds[i] = profiles.get(i).id;
17924        }
17925        mCurrentProfileIds = currentProfileIds;
17926
17927        synchronized (mUserProfileGroupIdsSelfLocked) {
17928            mUserProfileGroupIdsSelfLocked.clear();
17929            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17930            for (int i = 0; i < users.size(); i++) {
17931                UserInfo user = users.get(i);
17932                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17933                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17934                }
17935            }
17936        }
17937    }
17938
17939    private Set getProfileIdsLocked(int userId) {
17940        Set userIds = new HashSet<Integer>();
17941        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17942                userId, false /* enabledOnly */);
17943        for (UserInfo user : profiles) {
17944            userIds.add(Integer.valueOf(user.id));
17945        }
17946        return userIds;
17947    }
17948
17949    @Override
17950    public boolean switchUser(final int userId) {
17951        String userName;
17952        synchronized (this) {
17953            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17954            if (userInfo == null) {
17955                Slog.w(TAG, "No user info for user #" + userId);
17956                return false;
17957            }
17958            if (userInfo.isManagedProfile()) {
17959                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17960                return false;
17961            }
17962            userName = userInfo.name;
17963        }
17964        mHandler.removeMessages(START_USER_SWITCH_MSG);
17965        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17966        return true;
17967    }
17968
17969    private void showUserSwitchDialog(int userId, String userName) {
17970        // The dialog will show and then initiate the user switch by calling startUserInForeground
17971        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17972                true /* above system */);
17973        d.show();
17974    }
17975
17976    private boolean startUser(final int userId, final boolean foreground) {
17977        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17978                != PackageManager.PERMISSION_GRANTED) {
17979            String msg = "Permission Denial: switchUser() from pid="
17980                    + Binder.getCallingPid()
17981                    + ", uid=" + Binder.getCallingUid()
17982                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17983            Slog.w(TAG, msg);
17984            throw new SecurityException(msg);
17985        }
17986
17987        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17988
17989        final long ident = Binder.clearCallingIdentity();
17990        try {
17991            synchronized (this) {
17992                final int oldUserId = mCurrentUserId;
17993                if (oldUserId == userId) {
17994                    return true;
17995                }
17996
17997                mStackSupervisor.setLockTaskModeLocked(null, false);
17998
17999                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18000                if (userInfo == null) {
18001                    Slog.w(TAG, "No user info for user #" + userId);
18002                    return false;
18003                }
18004                if (foreground && userInfo.isManagedProfile()) {
18005                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18006                    return false;
18007                }
18008
18009                if (foreground) {
18010                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18011                            R.anim.screen_user_enter);
18012                }
18013
18014                boolean needStart = false;
18015
18016                // If the user we are switching to is not currently started, then
18017                // we need to start it now.
18018                if (mStartedUsers.get(userId) == null) {
18019                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18020                    updateStartedUserArrayLocked();
18021                    needStart = true;
18022                }
18023
18024                final Integer userIdInt = Integer.valueOf(userId);
18025                mUserLru.remove(userIdInt);
18026                mUserLru.add(userIdInt);
18027
18028                if (foreground) {
18029                    mCurrentUserId = userId;
18030                    updateCurrentProfileIdsLocked();
18031                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18032                    // Once the internal notion of the active user has switched, we lock the device
18033                    // with the option to show the user switcher on the keyguard.
18034                    mWindowManager.lockNow(null);
18035                } else {
18036                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18037                    updateCurrentProfileIdsLocked();
18038                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18039                    mUserLru.remove(currentUserIdInt);
18040                    mUserLru.add(currentUserIdInt);
18041                }
18042
18043                final UserStartedState uss = mStartedUsers.get(userId);
18044
18045                // Make sure user is in the started state.  If it is currently
18046                // stopping, we need to knock that off.
18047                if (uss.mState == UserStartedState.STATE_STOPPING) {
18048                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18049                    // so we can just fairly silently bring the user back from
18050                    // the almost-dead.
18051                    uss.mState = UserStartedState.STATE_RUNNING;
18052                    updateStartedUserArrayLocked();
18053                    needStart = true;
18054                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18055                    // This means ACTION_SHUTDOWN has been sent, so we will
18056                    // need to treat this as a new boot of the user.
18057                    uss.mState = UserStartedState.STATE_BOOTING;
18058                    updateStartedUserArrayLocked();
18059                    needStart = true;
18060                }
18061
18062                if (uss.mState == UserStartedState.STATE_BOOTING) {
18063                    // Booting up a new user, need to tell system services about it.
18064                    // Note that this is on the same handler as scheduling of broadcasts,
18065                    // which is important because it needs to go first.
18066                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18067                }
18068
18069                if (foreground) {
18070                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18071                            oldUserId));
18072                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18073                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18074                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18075                            oldUserId, userId, uss));
18076                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18077                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18078                }
18079
18080                if (needStart) {
18081                    // Send USER_STARTED broadcast
18082                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18083                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18084                            | Intent.FLAG_RECEIVER_FOREGROUND);
18085                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18086                    broadcastIntentLocked(null, null, intent,
18087                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18088                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18089                }
18090
18091                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18092                    if (userId != UserHandle.USER_OWNER) {
18093                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18094                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18095                        broadcastIntentLocked(null, null, intent, null,
18096                                new IIntentReceiver.Stub() {
18097                                    public void performReceive(Intent intent, int resultCode,
18098                                            String data, Bundle extras, boolean ordered,
18099                                            boolean sticky, int sendingUser) {
18100                                        onUserInitialized(uss, foreground, oldUserId, userId);
18101                                    }
18102                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18103                                true, false, MY_PID, Process.SYSTEM_UID,
18104                                userId);
18105                        uss.initializing = true;
18106                    } else {
18107                        getUserManagerLocked().makeInitialized(userInfo.id);
18108                    }
18109                }
18110
18111                if (foreground) {
18112                    if (!uss.initializing) {
18113                        moveUserToForeground(uss, oldUserId, userId);
18114                    }
18115                } else {
18116                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18117                }
18118
18119                if (needStart) {
18120                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18121                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18122                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18123                    broadcastIntentLocked(null, null, intent,
18124                            null, new IIntentReceiver.Stub() {
18125                                @Override
18126                                public void performReceive(Intent intent, int resultCode, String data,
18127                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18128                                        throws RemoteException {
18129                                }
18130                            }, 0, null, null,
18131                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18132                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18133                }
18134            }
18135        } finally {
18136            Binder.restoreCallingIdentity(ident);
18137        }
18138
18139        return true;
18140    }
18141
18142    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18143        long ident = Binder.clearCallingIdentity();
18144        try {
18145            Intent intent;
18146            if (oldUserId >= 0) {
18147                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18148                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18149                int count = profiles.size();
18150                for (int i = 0; i < count; i++) {
18151                    int profileUserId = profiles.get(i).id;
18152                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18153                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18154                            | Intent.FLAG_RECEIVER_FOREGROUND);
18155                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18156                    broadcastIntentLocked(null, null, intent,
18157                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18158                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18159                }
18160            }
18161            if (newUserId >= 0) {
18162                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18163                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18164                int count = profiles.size();
18165                for (int i = 0; i < count; i++) {
18166                    int profileUserId = profiles.get(i).id;
18167                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18168                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18169                            | Intent.FLAG_RECEIVER_FOREGROUND);
18170                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18171                    broadcastIntentLocked(null, null, intent,
18172                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18173                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18174                }
18175                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18176                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18177                        | Intent.FLAG_RECEIVER_FOREGROUND);
18178                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18179                broadcastIntentLocked(null, null, intent,
18180                        null, null, 0, null, null,
18181                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18182                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18183            }
18184        } finally {
18185            Binder.restoreCallingIdentity(ident);
18186        }
18187    }
18188
18189    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18190            final int newUserId) {
18191        final int N = mUserSwitchObservers.beginBroadcast();
18192        if (N > 0) {
18193            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18194                int mCount = 0;
18195                @Override
18196                public void sendResult(Bundle data) throws RemoteException {
18197                    synchronized (ActivityManagerService.this) {
18198                        if (mCurUserSwitchCallback == this) {
18199                            mCount++;
18200                            if (mCount == N) {
18201                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18202                            }
18203                        }
18204                    }
18205                }
18206            };
18207            synchronized (this) {
18208                uss.switching = true;
18209                mCurUserSwitchCallback = callback;
18210            }
18211            for (int i=0; i<N; i++) {
18212                try {
18213                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18214                            newUserId, callback);
18215                } catch (RemoteException e) {
18216                }
18217            }
18218        } else {
18219            synchronized (this) {
18220                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18221            }
18222        }
18223        mUserSwitchObservers.finishBroadcast();
18224    }
18225
18226    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18227        synchronized (this) {
18228            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18229            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18230        }
18231    }
18232
18233    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18234        mCurUserSwitchCallback = null;
18235        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18236        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18237                oldUserId, newUserId, uss));
18238    }
18239
18240    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18241        synchronized (this) {
18242            if (foreground) {
18243                moveUserToForeground(uss, oldUserId, newUserId);
18244            }
18245        }
18246
18247        completeSwitchAndInitalize(uss, newUserId, true, false);
18248    }
18249
18250    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18251        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18252        if (homeInFront) {
18253            startHomeActivityLocked(newUserId);
18254        } else {
18255            mStackSupervisor.resumeTopActivitiesLocked();
18256        }
18257        EventLogTags.writeAmSwitchUser(newUserId);
18258        getUserManagerLocked().userForeground(newUserId);
18259        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18260    }
18261
18262    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18263        completeSwitchAndInitalize(uss, newUserId, false, true);
18264    }
18265
18266    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18267            boolean clearInitializing, boolean clearSwitching) {
18268        boolean unfrozen = false;
18269        synchronized (this) {
18270            if (clearInitializing) {
18271                uss.initializing = false;
18272                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18273            }
18274            if (clearSwitching) {
18275                uss.switching = false;
18276            }
18277            if (!uss.switching && !uss.initializing) {
18278                mWindowManager.stopFreezingScreen();
18279                unfrozen = true;
18280            }
18281        }
18282        if (unfrozen) {
18283            final int N = mUserSwitchObservers.beginBroadcast();
18284            for (int i=0; i<N; i++) {
18285                try {
18286                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18287                } catch (RemoteException e) {
18288                }
18289            }
18290            mUserSwitchObservers.finishBroadcast();
18291        }
18292    }
18293
18294    void scheduleStartProfilesLocked() {
18295        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18296            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18297                    DateUtils.SECOND_IN_MILLIS);
18298        }
18299    }
18300
18301    void startProfilesLocked() {
18302        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18303        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18304                mCurrentUserId, false /* enabledOnly */);
18305        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18306        for (UserInfo user : profiles) {
18307            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18308                    && user.id != mCurrentUserId) {
18309                toStart.add(user);
18310            }
18311        }
18312        final int n = toStart.size();
18313        int i = 0;
18314        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18315            startUserInBackground(toStart.get(i).id);
18316        }
18317        if (i < n) {
18318            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18319        }
18320    }
18321
18322    void finishUserBoot(UserStartedState uss) {
18323        synchronized (this) {
18324            if (uss.mState == UserStartedState.STATE_BOOTING
18325                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18326                uss.mState = UserStartedState.STATE_RUNNING;
18327                final int userId = uss.mHandle.getIdentifier();
18328                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18329                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18330                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18331                broadcastIntentLocked(null, null, intent,
18332                        null, null, 0, null, null,
18333                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18334                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18335            }
18336        }
18337    }
18338
18339    void finishUserSwitch(UserStartedState uss) {
18340        synchronized (this) {
18341            finishUserBoot(uss);
18342
18343            startProfilesLocked();
18344
18345            int num = mUserLru.size();
18346            int i = 0;
18347            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18348                Integer oldUserId = mUserLru.get(i);
18349                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18350                if (oldUss == null) {
18351                    // Shouldn't happen, but be sane if it does.
18352                    mUserLru.remove(i);
18353                    num--;
18354                    continue;
18355                }
18356                if (oldUss.mState == UserStartedState.STATE_STOPPING
18357                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18358                    // This user is already stopping, doesn't count.
18359                    num--;
18360                    i++;
18361                    continue;
18362                }
18363                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18364                    // Owner and current can't be stopped, but count as running.
18365                    i++;
18366                    continue;
18367                }
18368                // This is a user to be stopped.
18369                stopUserLocked(oldUserId, null);
18370                num--;
18371                i++;
18372            }
18373        }
18374    }
18375
18376    @Override
18377    public int stopUser(final int userId, final IStopUserCallback callback) {
18378        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18379                != PackageManager.PERMISSION_GRANTED) {
18380            String msg = "Permission Denial: switchUser() from pid="
18381                    + Binder.getCallingPid()
18382                    + ", uid=" + Binder.getCallingUid()
18383                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18384            Slog.w(TAG, msg);
18385            throw new SecurityException(msg);
18386        }
18387        if (userId <= 0) {
18388            throw new IllegalArgumentException("Can't stop primary user " + userId);
18389        }
18390        synchronized (this) {
18391            return stopUserLocked(userId, callback);
18392        }
18393    }
18394
18395    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18396        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18397        if (mCurrentUserId == userId) {
18398            return ActivityManager.USER_OP_IS_CURRENT;
18399        }
18400
18401        final UserStartedState uss = mStartedUsers.get(userId);
18402        if (uss == null) {
18403            // User is not started, nothing to do...  but we do need to
18404            // callback if requested.
18405            if (callback != null) {
18406                mHandler.post(new Runnable() {
18407                    @Override
18408                    public void run() {
18409                        try {
18410                            callback.userStopped(userId);
18411                        } catch (RemoteException e) {
18412                        }
18413                    }
18414                });
18415            }
18416            return ActivityManager.USER_OP_SUCCESS;
18417        }
18418
18419        if (callback != null) {
18420            uss.mStopCallbacks.add(callback);
18421        }
18422
18423        if (uss.mState != UserStartedState.STATE_STOPPING
18424                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18425            uss.mState = UserStartedState.STATE_STOPPING;
18426            updateStartedUserArrayLocked();
18427
18428            long ident = Binder.clearCallingIdentity();
18429            try {
18430                // We are going to broadcast ACTION_USER_STOPPING and then
18431                // once that is done send a final ACTION_SHUTDOWN and then
18432                // stop the user.
18433                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18434                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18435                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18436                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18437                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18438                // This is the result receiver for the final shutdown broadcast.
18439                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18440                    @Override
18441                    public void performReceive(Intent intent, int resultCode, String data,
18442                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18443                        finishUserStop(uss);
18444                    }
18445                };
18446                // This is the result receiver for the initial stopping broadcast.
18447                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18448                    @Override
18449                    public void performReceive(Intent intent, int resultCode, String data,
18450                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18451                        // On to the next.
18452                        synchronized (ActivityManagerService.this) {
18453                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18454                                // Whoops, we are being started back up.  Abort, abort!
18455                                return;
18456                            }
18457                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18458                        }
18459                        mBatteryStatsService.noteEvent(
18460                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18461                                Integer.toString(userId), userId);
18462                        mSystemServiceManager.stopUser(userId);
18463                        broadcastIntentLocked(null, null, shutdownIntent,
18464                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18465                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18466                    }
18467                };
18468                // Kick things off.
18469                broadcastIntentLocked(null, null, stoppingIntent,
18470                        null, stoppingReceiver, 0, null, null,
18471                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18472                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18473            } finally {
18474                Binder.restoreCallingIdentity(ident);
18475            }
18476        }
18477
18478        return ActivityManager.USER_OP_SUCCESS;
18479    }
18480
18481    void finishUserStop(UserStartedState uss) {
18482        final int userId = uss.mHandle.getIdentifier();
18483        boolean stopped;
18484        ArrayList<IStopUserCallback> callbacks;
18485        synchronized (this) {
18486            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18487            if (mStartedUsers.get(userId) != uss) {
18488                stopped = false;
18489            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18490                stopped = false;
18491            } else {
18492                stopped = true;
18493                // User can no longer run.
18494                mStartedUsers.remove(userId);
18495                mUserLru.remove(Integer.valueOf(userId));
18496                updateStartedUserArrayLocked();
18497
18498                // Clean up all state and processes associated with the user.
18499                // Kill all the processes for the user.
18500                forceStopUserLocked(userId, "finish user");
18501            }
18502
18503            // Explicitly remove the old information in mRecentTasks.
18504            removeRecentTasksForUserLocked(userId);
18505        }
18506
18507        for (int i=0; i<callbacks.size(); i++) {
18508            try {
18509                if (stopped) callbacks.get(i).userStopped(userId);
18510                else callbacks.get(i).userStopAborted(userId);
18511            } catch (RemoteException e) {
18512            }
18513        }
18514
18515        if (stopped) {
18516            mSystemServiceManager.cleanupUser(userId);
18517            synchronized (this) {
18518                mStackSupervisor.removeUserLocked(userId);
18519            }
18520        }
18521    }
18522
18523    @Override
18524    public UserInfo getCurrentUser() {
18525        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18526                != PackageManager.PERMISSION_GRANTED) && (
18527                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18528                != PackageManager.PERMISSION_GRANTED)) {
18529            String msg = "Permission Denial: getCurrentUser() from pid="
18530                    + Binder.getCallingPid()
18531                    + ", uid=" + Binder.getCallingUid()
18532                    + " requires " + INTERACT_ACROSS_USERS;
18533            Slog.w(TAG, msg);
18534            throw new SecurityException(msg);
18535        }
18536        synchronized (this) {
18537            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18538        }
18539    }
18540
18541    int getCurrentUserIdLocked() {
18542        return mCurrentUserId;
18543    }
18544
18545    @Override
18546    public boolean isUserRunning(int userId, boolean orStopped) {
18547        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18548                != PackageManager.PERMISSION_GRANTED) {
18549            String msg = "Permission Denial: isUserRunning() from pid="
18550                    + Binder.getCallingPid()
18551                    + ", uid=" + Binder.getCallingUid()
18552                    + " requires " + INTERACT_ACROSS_USERS;
18553            Slog.w(TAG, msg);
18554            throw new SecurityException(msg);
18555        }
18556        synchronized (this) {
18557            return isUserRunningLocked(userId, orStopped);
18558        }
18559    }
18560
18561    boolean isUserRunningLocked(int userId, boolean orStopped) {
18562        UserStartedState state = mStartedUsers.get(userId);
18563        if (state == null) {
18564            return false;
18565        }
18566        if (orStopped) {
18567            return true;
18568        }
18569        return state.mState != UserStartedState.STATE_STOPPING
18570                && state.mState != UserStartedState.STATE_SHUTDOWN;
18571    }
18572
18573    @Override
18574    public int[] getRunningUserIds() {
18575        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18576                != PackageManager.PERMISSION_GRANTED) {
18577            String msg = "Permission Denial: isUserRunning() from pid="
18578                    + Binder.getCallingPid()
18579                    + ", uid=" + Binder.getCallingUid()
18580                    + " requires " + INTERACT_ACROSS_USERS;
18581            Slog.w(TAG, msg);
18582            throw new SecurityException(msg);
18583        }
18584        synchronized (this) {
18585            return mStartedUserArray;
18586        }
18587    }
18588
18589    private void updateStartedUserArrayLocked() {
18590        int num = 0;
18591        for (int i=0; i<mStartedUsers.size();  i++) {
18592            UserStartedState uss = mStartedUsers.valueAt(i);
18593            // This list does not include stopping users.
18594            if (uss.mState != UserStartedState.STATE_STOPPING
18595                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18596                num++;
18597            }
18598        }
18599        mStartedUserArray = new int[num];
18600        num = 0;
18601        for (int i=0; i<mStartedUsers.size();  i++) {
18602            UserStartedState uss = mStartedUsers.valueAt(i);
18603            if (uss.mState != UserStartedState.STATE_STOPPING
18604                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18605                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18606                num++;
18607            }
18608        }
18609    }
18610
18611    @Override
18612    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18613        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18614                != PackageManager.PERMISSION_GRANTED) {
18615            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18616                    + Binder.getCallingPid()
18617                    + ", uid=" + Binder.getCallingUid()
18618                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18619            Slog.w(TAG, msg);
18620            throw new SecurityException(msg);
18621        }
18622
18623        mUserSwitchObservers.register(observer);
18624    }
18625
18626    @Override
18627    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18628        mUserSwitchObservers.unregister(observer);
18629    }
18630
18631    private boolean userExists(int userId) {
18632        if (userId == 0) {
18633            return true;
18634        }
18635        UserManagerService ums = getUserManagerLocked();
18636        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18637    }
18638
18639    int[] getUsersLocked() {
18640        UserManagerService ums = getUserManagerLocked();
18641        return ums != null ? ums.getUserIds() : new int[] { 0 };
18642    }
18643
18644    UserManagerService getUserManagerLocked() {
18645        if (mUserManager == null) {
18646            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18647            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18648        }
18649        return mUserManager;
18650    }
18651
18652    private int applyUserId(int uid, int userId) {
18653        return UserHandle.getUid(userId, uid);
18654    }
18655
18656    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18657        if (info == null) return null;
18658        ApplicationInfo newInfo = new ApplicationInfo(info);
18659        newInfo.uid = applyUserId(info.uid, userId);
18660        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18661                + info.packageName;
18662        return newInfo;
18663    }
18664
18665    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18666        if (aInfo == null
18667                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18668            return aInfo;
18669        }
18670
18671        ActivityInfo info = new ActivityInfo(aInfo);
18672        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18673        return info;
18674    }
18675
18676    private final class LocalService extends ActivityManagerInternal {
18677        @Override
18678        public void goingToSleep() {
18679            ActivityManagerService.this.goingToSleep();
18680        }
18681
18682        @Override
18683        public void wakingUp() {
18684            ActivityManagerService.this.wakingUp();
18685        }
18686
18687        @Override
18688        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18689                String processName, String abiOverride, int uid, Runnable crashHandler) {
18690            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18691                    processName, abiOverride, uid, crashHandler);
18692        }
18693    }
18694
18695    /**
18696     * An implementation of IAppTask, that allows an app to manage its own tasks via
18697     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18698     * only the process that calls getAppTasks() can call the AppTask methods.
18699     */
18700    class AppTaskImpl extends IAppTask.Stub {
18701        private int mTaskId;
18702        private int mCallingUid;
18703
18704        public AppTaskImpl(int taskId, int callingUid) {
18705            mTaskId = taskId;
18706            mCallingUid = callingUid;
18707        }
18708
18709        private void checkCaller() {
18710            if (mCallingUid != Binder.getCallingUid()) {
18711                throw new SecurityException("Caller " + mCallingUid
18712                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18713            }
18714        }
18715
18716        @Override
18717        public void finishAndRemoveTask() {
18718            checkCaller();
18719
18720            synchronized (ActivityManagerService.this) {
18721                long origId = Binder.clearCallingIdentity();
18722                try {
18723                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18724                    if (tr == null) {
18725                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18726                    }
18727                    // Only kill the process if we are not a new document
18728                    int flags = tr.getBaseIntent().getFlags();
18729                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18730                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18731                    removeTaskByIdLocked(mTaskId,
18732                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18733                } finally {
18734                    Binder.restoreCallingIdentity(origId);
18735                }
18736            }
18737        }
18738
18739        @Override
18740        public ActivityManager.RecentTaskInfo getTaskInfo() {
18741            checkCaller();
18742
18743            synchronized (ActivityManagerService.this) {
18744                long origId = Binder.clearCallingIdentity();
18745                try {
18746                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18747                    if (tr == null) {
18748                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18749                    }
18750                    return createRecentTaskInfoFromTaskRecord(tr);
18751                } finally {
18752                    Binder.restoreCallingIdentity(origId);
18753                }
18754            }
18755        }
18756
18757        @Override
18758        public void moveToFront() {
18759            checkCaller();
18760
18761            final TaskRecord tr;
18762            synchronized (ActivityManagerService.this) {
18763                tr = recentTaskForIdLocked(mTaskId);
18764                if (tr == null) {
18765                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18766                }
18767                if (tr.getRootActivity() != null) {
18768                    long origId = Binder.clearCallingIdentity();
18769                    try {
18770                        moveTaskToFrontLocked(tr.taskId, 0, null);
18771                        return;
18772                    } finally {
18773                        Binder.restoreCallingIdentity(origId);
18774                    }
18775                }
18776            }
18777
18778            startActivityFromRecentsInner(tr.taskId, null);
18779        }
18780
18781        @Override
18782        public int startActivity(IBinder whoThread, String callingPackage,
18783                Intent intent, String resolvedType, Bundle options) {
18784            checkCaller();
18785
18786            int callingUser = UserHandle.getCallingUserId();
18787            TaskRecord tr;
18788            IApplicationThread appThread;
18789            synchronized (ActivityManagerService.this) {
18790                tr = recentTaskForIdLocked(mTaskId);
18791                if (tr == null) {
18792                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18793                }
18794                appThread = ApplicationThreadNative.asInterface(whoThread);
18795                if (appThread == null) {
18796                    throw new IllegalArgumentException("Bad app thread " + appThread);
18797                }
18798            }
18799            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18800                    resolvedType, null, null, null, null, 0, 0, null, null,
18801                    null, options, callingUser, null, tr);
18802        }
18803
18804        @Override
18805        public void setExcludeFromRecents(boolean exclude) {
18806            checkCaller();
18807
18808            synchronized (ActivityManagerService.this) {
18809                long origId = Binder.clearCallingIdentity();
18810                try {
18811                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18812                    if (tr == null) {
18813                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18814                    }
18815                    Intent intent = tr.getBaseIntent();
18816                    if (exclude) {
18817                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18818                    } else {
18819                        intent.setFlags(intent.getFlags()
18820                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18821                    }
18822                } finally {
18823                    Binder.restoreCallingIdentity(origId);
18824                }
18825            }
18826        }
18827    }
18828}
18829