ActivityManagerService.java revision a42c0de977fcd06e6c7a5be5b072fd661101ac58
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    // Holds the current foreground user's id
1111    int mCurrentUserId = 0;
1112    // Holds the target user's id during a user switch
1113    int mTargetUserId = UserHandle.USER_NULL;
1114    // If there are multiple profiles for the current user, their ids are here
1115    // Currently only the primary user can have managed profiles
1116    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1117
1118    /**
1119     * Mapping from each known user ID to the profile group ID it is associated with.
1120     */
1121    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1122
1123    private UserManagerService mUserManager;
1124
1125    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1126        final ProcessRecord mApp;
1127        final int mPid;
1128        final IApplicationThread mAppThread;
1129
1130        AppDeathRecipient(ProcessRecord app, int pid,
1131                IApplicationThread thread) {
1132            if (localLOGV) Slog.v(
1133                TAG, "New death recipient " + this
1134                + " for thread " + thread.asBinder());
1135            mApp = app;
1136            mPid = pid;
1137            mAppThread = thread;
1138        }
1139
1140        @Override
1141        public void binderDied() {
1142            if (localLOGV) Slog.v(
1143                TAG, "Death received in " + this
1144                + " for thread " + mAppThread.asBinder());
1145            synchronized(ActivityManagerService.this) {
1146                appDiedLocked(mApp, mPid, mAppThread);
1147            }
1148        }
1149    }
1150
1151    static final int SHOW_ERROR_MSG = 1;
1152    static final int SHOW_NOT_RESPONDING_MSG = 2;
1153    static final int SHOW_FACTORY_ERROR_MSG = 3;
1154    static final int UPDATE_CONFIGURATION_MSG = 4;
1155    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1156    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1157    static final int SERVICE_TIMEOUT_MSG = 12;
1158    static final int UPDATE_TIME_ZONE = 13;
1159    static final int SHOW_UID_ERROR_MSG = 14;
1160    static final int IM_FEELING_LUCKY_MSG = 15;
1161    static final int PROC_START_TIMEOUT_MSG = 20;
1162    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1163    static final int KILL_APPLICATION_MSG = 22;
1164    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1165    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1166    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1167    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1168    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1169    static final int CLEAR_DNS_CACHE_MSG = 28;
1170    static final int UPDATE_HTTP_PROXY_MSG = 29;
1171    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1172    static final int DISPATCH_PROCESSES_CHANGED = 31;
1173    static final int DISPATCH_PROCESS_DIED = 32;
1174    static final int REPORT_MEM_USAGE_MSG = 33;
1175    static final int REPORT_USER_SWITCH_MSG = 34;
1176    static final int CONTINUE_USER_SWITCH_MSG = 35;
1177    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1178    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1179    static final int PERSIST_URI_GRANTS_MSG = 38;
1180    static final int REQUEST_ALL_PSS_MSG = 39;
1181    static final int START_PROFILES_MSG = 40;
1182    static final int UPDATE_TIME = 41;
1183    static final int SYSTEM_USER_START_MSG = 42;
1184    static final int SYSTEM_USER_CURRENT_MSG = 43;
1185    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1186    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1187    static final int START_USER_SWITCH_MSG = 46;
1188
1189    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1190    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1191    static final int FIRST_COMPAT_MODE_MSG = 300;
1192    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1193
1194    AlertDialog mUidAlert;
1195    CompatModeDialog mCompatModeDialog;
1196    long mLastMemUsageReportTime = 0;
1197
1198    private LockToAppRequestDialog mLockToAppRequest;
1199
1200    /**
1201     * Flag whether the current user is a "monkey", i.e. whether
1202     * the UI is driven by a UI automation tool.
1203     */
1204    private boolean mUserIsMonkey;
1205
1206    /** Flag whether the device has a Recents UI */
1207    boolean mHasRecents;
1208
1209    /** The dimensions of the thumbnails in the Recents UI. */
1210    int mThumbnailWidth;
1211    int mThumbnailHeight;
1212
1213    final ServiceThread mHandlerThread;
1214    final MainHandler mHandler;
1215
1216    final class MainHandler extends Handler {
1217        public MainHandler(Looper looper) {
1218            super(looper, null, true);
1219        }
1220
1221        @Override
1222        public void handleMessage(Message msg) {
1223            switch (msg.what) {
1224            case SHOW_ERROR_MSG: {
1225                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1226                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1227                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1228                synchronized (ActivityManagerService.this) {
1229                    ProcessRecord proc = (ProcessRecord)data.get("app");
1230                    AppErrorResult res = (AppErrorResult) data.get("result");
1231                    if (proc != null && proc.crashDialog != null) {
1232                        Slog.e(TAG, "App already has crash dialog: " + proc);
1233                        if (res != null) {
1234                            res.set(0);
1235                        }
1236                        return;
1237                    }
1238                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1239                            >= Process.FIRST_APPLICATION_UID
1240                            && proc.pid != MY_PID);
1241                    for (int userId : mCurrentProfileIds) {
1242                        isBackground &= (proc.userId != userId);
1243                    }
1244                    if (isBackground && !showBackground) {
1245                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1246                        if (res != null) {
1247                            res.set(0);
1248                        }
1249                        return;
1250                    }
1251                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1252                        Dialog d = new AppErrorDialog(mContext,
1253                                ActivityManagerService.this, res, proc);
1254                        d.show();
1255                        proc.crashDialog = d;
1256                    } else {
1257                        // The device is asleep, so just pretend that the user
1258                        // saw a crash dialog and hit "force quit".
1259                        if (res != null) {
1260                            res.set(0);
1261                        }
1262                    }
1263                }
1264
1265                ensureBootCompleted();
1266            } break;
1267            case SHOW_NOT_RESPONDING_MSG: {
1268                synchronized (ActivityManagerService.this) {
1269                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1270                    ProcessRecord proc = (ProcessRecord)data.get("app");
1271                    if (proc != null && proc.anrDialog != null) {
1272                        Slog.e(TAG, "App already has anr dialog: " + proc);
1273                        return;
1274                    }
1275
1276                    Intent intent = new Intent("android.intent.action.ANR");
1277                    if (!mProcessesReady) {
1278                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1279                                | Intent.FLAG_RECEIVER_FOREGROUND);
1280                    }
1281                    broadcastIntentLocked(null, null, intent,
1282                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1283                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1284
1285                    if (mShowDialogs) {
1286                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1287                                mContext, proc, (ActivityRecord)data.get("activity"),
1288                                msg.arg1 != 0);
1289                        d.show();
1290                        proc.anrDialog = d;
1291                    } else {
1292                        // Just kill the app if there is no dialog to be shown.
1293                        killAppAtUsersRequest(proc, null);
1294                    }
1295                }
1296
1297                ensureBootCompleted();
1298            } break;
1299            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1300                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1301                synchronized (ActivityManagerService.this) {
1302                    ProcessRecord proc = (ProcessRecord) data.get("app");
1303                    if (proc == null) {
1304                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1305                        break;
1306                    }
1307                    if (proc.crashDialog != null) {
1308                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1309                        return;
1310                    }
1311                    AppErrorResult res = (AppErrorResult) data.get("result");
1312                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1313                        Dialog d = new StrictModeViolationDialog(mContext,
1314                                ActivityManagerService.this, res, proc);
1315                        d.show();
1316                        proc.crashDialog = d;
1317                    } else {
1318                        // The device is asleep, so just pretend that the user
1319                        // saw a crash dialog and hit "force quit".
1320                        res.set(0);
1321                    }
1322                }
1323                ensureBootCompleted();
1324            } break;
1325            case SHOW_FACTORY_ERROR_MSG: {
1326                Dialog d = new FactoryErrorDialog(
1327                    mContext, msg.getData().getCharSequence("msg"));
1328                d.show();
1329                ensureBootCompleted();
1330            } break;
1331            case UPDATE_CONFIGURATION_MSG: {
1332                final ContentResolver resolver = mContext.getContentResolver();
1333                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1334            } break;
1335            case GC_BACKGROUND_PROCESSES_MSG: {
1336                synchronized (ActivityManagerService.this) {
1337                    performAppGcsIfAppropriateLocked();
1338                }
1339            } break;
1340            case WAIT_FOR_DEBUGGER_MSG: {
1341                synchronized (ActivityManagerService.this) {
1342                    ProcessRecord app = (ProcessRecord)msg.obj;
1343                    if (msg.arg1 != 0) {
1344                        if (!app.waitedForDebugger) {
1345                            Dialog d = new AppWaitingForDebuggerDialog(
1346                                    ActivityManagerService.this,
1347                                    mContext, app);
1348                            app.waitDialog = d;
1349                            app.waitedForDebugger = true;
1350                            d.show();
1351                        }
1352                    } else {
1353                        if (app.waitDialog != null) {
1354                            app.waitDialog.dismiss();
1355                            app.waitDialog = null;
1356                        }
1357                    }
1358                }
1359            } break;
1360            case SERVICE_TIMEOUT_MSG: {
1361                if (mDidDexOpt) {
1362                    mDidDexOpt = false;
1363                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1364                    nmsg.obj = msg.obj;
1365                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1366                    return;
1367                }
1368                mServices.serviceTimeout((ProcessRecord)msg.obj);
1369            } break;
1370            case UPDATE_TIME_ZONE: {
1371                synchronized (ActivityManagerService.this) {
1372                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1373                        ProcessRecord r = mLruProcesses.get(i);
1374                        if (r.thread != null) {
1375                            try {
1376                                r.thread.updateTimeZone();
1377                            } catch (RemoteException ex) {
1378                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1379                            }
1380                        }
1381                    }
1382                }
1383            } break;
1384            case CLEAR_DNS_CACHE_MSG: {
1385                synchronized (ActivityManagerService.this) {
1386                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1387                        ProcessRecord r = mLruProcesses.get(i);
1388                        if (r.thread != null) {
1389                            try {
1390                                r.thread.clearDnsCache();
1391                            } catch (RemoteException ex) {
1392                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1393                            }
1394                        }
1395                    }
1396                }
1397            } break;
1398            case UPDATE_HTTP_PROXY_MSG: {
1399                ProxyInfo proxy = (ProxyInfo)msg.obj;
1400                String host = "";
1401                String port = "";
1402                String exclList = "";
1403                Uri pacFileUrl = Uri.EMPTY;
1404                if (proxy != null) {
1405                    host = proxy.getHost();
1406                    port = Integer.toString(proxy.getPort());
1407                    exclList = proxy.getExclusionListAsString();
1408                    pacFileUrl = proxy.getPacFileUrl();
1409                }
1410                synchronized (ActivityManagerService.this) {
1411                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1412                        ProcessRecord r = mLruProcesses.get(i);
1413                        if (r.thread != null) {
1414                            try {
1415                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1416                            } catch (RemoteException ex) {
1417                                Slog.w(TAG, "Failed to update http proxy for: " +
1418                                        r.info.processName);
1419                            }
1420                        }
1421                    }
1422                }
1423            } break;
1424            case SHOW_UID_ERROR_MSG: {
1425                String title = "System UIDs Inconsistent";
1426                String text = "UIDs on the system are inconsistent, you need to wipe your"
1427                        + " data partition or your device will be unstable.";
1428                Log.e(TAG, title + ": " + text);
1429                if (mShowDialogs) {
1430                    // XXX This is a temporary dialog, no need to localize.
1431                    AlertDialog d = new BaseErrorDialog(mContext);
1432                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1433                    d.setCancelable(false);
1434                    d.setTitle(title);
1435                    d.setMessage(text);
1436                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1437                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1438                    mUidAlert = d;
1439                    d.show();
1440                }
1441            } break;
1442            case IM_FEELING_LUCKY_MSG: {
1443                if (mUidAlert != null) {
1444                    mUidAlert.dismiss();
1445                    mUidAlert = null;
1446                }
1447            } break;
1448            case PROC_START_TIMEOUT_MSG: {
1449                if (mDidDexOpt) {
1450                    mDidDexOpt = false;
1451                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1452                    nmsg.obj = msg.obj;
1453                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1454                    return;
1455                }
1456                ProcessRecord app = (ProcessRecord)msg.obj;
1457                synchronized (ActivityManagerService.this) {
1458                    processStartTimedOutLocked(app);
1459                }
1460            } break;
1461            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1462                synchronized (ActivityManagerService.this) {
1463                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1464                }
1465            } break;
1466            case KILL_APPLICATION_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    int appid = msg.arg1;
1469                    boolean restart = (msg.arg2 == 1);
1470                    Bundle bundle = (Bundle)msg.obj;
1471                    String pkg = bundle.getString("pkg");
1472                    String reason = bundle.getString("reason");
1473                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1474                            false, UserHandle.USER_ALL, reason);
1475                }
1476            } break;
1477            case FINALIZE_PENDING_INTENT_MSG: {
1478                ((PendingIntentRecord)msg.obj).completeFinalize();
1479            } break;
1480            case POST_HEAVY_NOTIFICATION_MSG: {
1481                INotificationManager inm = NotificationManager.getService();
1482                if (inm == null) {
1483                    return;
1484                }
1485
1486                ActivityRecord root = (ActivityRecord)msg.obj;
1487                ProcessRecord process = root.app;
1488                if (process == null) {
1489                    return;
1490                }
1491
1492                try {
1493                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1494                    String text = mContext.getString(R.string.heavy_weight_notification,
1495                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1496                    Notification notification = new Notification();
1497                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1498                    notification.when = 0;
1499                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1500                    notification.tickerText = text;
1501                    notification.defaults = 0; // please be quiet
1502                    notification.sound = null;
1503                    notification.vibrate = null;
1504                    notification.color = mContext.getResources().getColor(
1505                            com.android.internal.R.color.system_notification_accent_color);
1506                    notification.setLatestEventInfo(context, text,
1507                            mContext.getText(R.string.heavy_weight_notification_detail),
1508                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1509                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1510                                    new UserHandle(root.userId)));
1511
1512                    try {
1513                        int[] outId = new int[1];
1514                        inm.enqueueNotificationWithTag("android", "android", null,
1515                                R.string.heavy_weight_notification,
1516                                notification, outId, root.userId);
1517                    } catch (RuntimeException e) {
1518                        Slog.w(ActivityManagerService.TAG,
1519                                "Error showing notification for heavy-weight app", e);
1520                    } catch (RemoteException e) {
1521                    }
1522                } catch (NameNotFoundException e) {
1523                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1524                }
1525            } break;
1526            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1527                INotificationManager inm = NotificationManager.getService();
1528                if (inm == null) {
1529                    return;
1530                }
1531                try {
1532                    inm.cancelNotificationWithTag("android", null,
1533                            R.string.heavy_weight_notification,  msg.arg1);
1534                } catch (RuntimeException e) {
1535                    Slog.w(ActivityManagerService.TAG,
1536                            "Error canceling notification for service", e);
1537                } catch (RemoteException e) {
1538                }
1539            } break;
1540            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1541                synchronized (ActivityManagerService.this) {
1542                    checkExcessivePowerUsageLocked(true);
1543                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1544                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1545                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1546                }
1547            } break;
1548            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1549                synchronized (ActivityManagerService.this) {
1550                    ActivityRecord ar = (ActivityRecord)msg.obj;
1551                    if (mCompatModeDialog != null) {
1552                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1553                                ar.info.applicationInfo.packageName)) {
1554                            return;
1555                        }
1556                        mCompatModeDialog.dismiss();
1557                        mCompatModeDialog = null;
1558                    }
1559                    if (ar != null && false) {
1560                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1561                                ar.packageName)) {
1562                            int mode = mCompatModePackages.computeCompatModeLocked(
1563                                    ar.info.applicationInfo);
1564                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1565                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1566                                mCompatModeDialog = new CompatModeDialog(
1567                                        ActivityManagerService.this, mContext,
1568                                        ar.info.applicationInfo);
1569                                mCompatModeDialog.show();
1570                            }
1571                        }
1572                    }
1573                }
1574                break;
1575            }
1576            case DISPATCH_PROCESSES_CHANGED: {
1577                dispatchProcessesChanged();
1578                break;
1579            }
1580            case DISPATCH_PROCESS_DIED: {
1581                final int pid = msg.arg1;
1582                final int uid = msg.arg2;
1583                dispatchProcessDied(pid, uid);
1584                break;
1585            }
1586            case REPORT_MEM_USAGE_MSG: {
1587                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1588                Thread thread = new Thread() {
1589                    @Override public void run() {
1590                        final SparseArray<ProcessMemInfo> infoMap
1591                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1592                        for (int i=0, N=memInfos.size(); i<N; i++) {
1593                            ProcessMemInfo mi = memInfos.get(i);
1594                            infoMap.put(mi.pid, mi);
1595                        }
1596                        updateCpuStatsNow();
1597                        synchronized (mProcessCpuThread) {
1598                            final int N = mProcessCpuTracker.countStats();
1599                            for (int i=0; i<N; i++) {
1600                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1601                                if (st.vsize > 0) {
1602                                    long pss = Debug.getPss(st.pid, null);
1603                                    if (pss > 0) {
1604                                        if (infoMap.indexOfKey(st.pid) < 0) {
1605                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1606                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1607                                            mi.pss = pss;
1608                                            memInfos.add(mi);
1609                                        }
1610                                    }
1611                                }
1612                            }
1613                        }
1614
1615                        long totalPss = 0;
1616                        for (int i=0, N=memInfos.size(); i<N; i++) {
1617                            ProcessMemInfo mi = memInfos.get(i);
1618                            if (mi.pss == 0) {
1619                                mi.pss = Debug.getPss(mi.pid, null);
1620                            }
1621                            totalPss += mi.pss;
1622                        }
1623                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1624                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1625                                if (lhs.oomAdj != rhs.oomAdj) {
1626                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1627                                }
1628                                if (lhs.pss != rhs.pss) {
1629                                    return lhs.pss < rhs.pss ? 1 : -1;
1630                                }
1631                                return 0;
1632                            }
1633                        });
1634
1635                        StringBuilder tag = new StringBuilder(128);
1636                        StringBuilder stack = new StringBuilder(128);
1637                        tag.append("Low on memory -- ");
1638                        appendMemBucket(tag, totalPss, "total", false);
1639                        appendMemBucket(stack, totalPss, "total", true);
1640
1641                        StringBuilder logBuilder = new StringBuilder(1024);
1642                        logBuilder.append("Low on memory:\n");
1643
1644                        boolean firstLine = true;
1645                        int lastOomAdj = Integer.MIN_VALUE;
1646                        for (int i=0, N=memInfos.size(); i<N; i++) {
1647                            ProcessMemInfo mi = memInfos.get(i);
1648
1649                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1650                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1651                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1652                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1653                                if (lastOomAdj != mi.oomAdj) {
1654                                    lastOomAdj = mi.oomAdj;
1655                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1656                                        tag.append(" / ");
1657                                    }
1658                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1659                                        if (firstLine) {
1660                                            stack.append(":");
1661                                            firstLine = false;
1662                                        }
1663                                        stack.append("\n\t at ");
1664                                    } else {
1665                                        stack.append("$");
1666                                    }
1667                                } else {
1668                                    tag.append(" ");
1669                                    stack.append("$");
1670                                }
1671                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1672                                    appendMemBucket(tag, mi.pss, mi.name, false);
1673                                }
1674                                appendMemBucket(stack, mi.pss, mi.name, true);
1675                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1676                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1677                                    stack.append("(");
1678                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1679                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1680                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1681                                            stack.append(":");
1682                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1683                                        }
1684                                    }
1685                                    stack.append(")");
1686                                }
1687                            }
1688
1689                            logBuilder.append("  ");
1690                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1691                            logBuilder.append(' ');
1692                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1693                            logBuilder.append(' ');
1694                            ProcessList.appendRamKb(logBuilder, mi.pss);
1695                            logBuilder.append(" kB: ");
1696                            logBuilder.append(mi.name);
1697                            logBuilder.append(" (");
1698                            logBuilder.append(mi.pid);
1699                            logBuilder.append(") ");
1700                            logBuilder.append(mi.adjType);
1701                            logBuilder.append('\n');
1702                            if (mi.adjReason != null) {
1703                                logBuilder.append("                      ");
1704                                logBuilder.append(mi.adjReason);
1705                                logBuilder.append('\n');
1706                            }
1707                        }
1708
1709                        logBuilder.append("           ");
1710                        ProcessList.appendRamKb(logBuilder, totalPss);
1711                        logBuilder.append(" kB: TOTAL\n");
1712
1713                        long[] infos = new long[Debug.MEMINFO_COUNT];
1714                        Debug.getMemInfo(infos);
1715                        logBuilder.append("  MemInfo: ");
1716                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1717                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1718                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1719                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1720                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1721                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1722                            logBuilder.append("  ZRAM: ");
1723                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1724                            logBuilder.append(" kB RAM, ");
1725                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1726                            logBuilder.append(" kB swap total, ");
1727                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1728                            logBuilder.append(" kB swap free\n");
1729                        }
1730                        Slog.i(TAG, logBuilder.toString());
1731
1732                        StringBuilder dropBuilder = new StringBuilder(1024);
1733                        /*
1734                        StringWriter oomSw = new StringWriter();
1735                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1736                        StringWriter catSw = new StringWriter();
1737                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1738                        String[] emptyArgs = new String[] { };
1739                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1740                        oomPw.flush();
1741                        String oomString = oomSw.toString();
1742                        */
1743                        dropBuilder.append(stack);
1744                        dropBuilder.append('\n');
1745                        dropBuilder.append('\n');
1746                        dropBuilder.append(logBuilder);
1747                        dropBuilder.append('\n');
1748                        /*
1749                        dropBuilder.append(oomString);
1750                        dropBuilder.append('\n');
1751                        */
1752                        StringWriter catSw = new StringWriter();
1753                        synchronized (ActivityManagerService.this) {
1754                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1755                            String[] emptyArgs = new String[] { };
1756                            catPw.println();
1757                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1758                            catPw.println();
1759                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1760                                    false, false, null);
1761                            catPw.println();
1762                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1763                            catPw.flush();
1764                        }
1765                        dropBuilder.append(catSw.toString());
1766                        addErrorToDropBox("lowmem", null, "system_server", null,
1767                                null, tag.toString(), dropBuilder.toString(), null, null);
1768                        //Slog.i(TAG, "Sent to dropbox:");
1769                        //Slog.i(TAG, dropBuilder.toString());
1770                        synchronized (ActivityManagerService.this) {
1771                            long now = SystemClock.uptimeMillis();
1772                            if (mLastMemUsageReportTime < now) {
1773                                mLastMemUsageReportTime = now;
1774                            }
1775                        }
1776                    }
1777                };
1778                thread.start();
1779                break;
1780            }
1781            case START_USER_SWITCH_MSG: {
1782                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1783                break;
1784            }
1785            case REPORT_USER_SWITCH_MSG: {
1786                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1787                break;
1788            }
1789            case CONTINUE_USER_SWITCH_MSG: {
1790                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1791                break;
1792            }
1793            case USER_SWITCH_TIMEOUT_MSG: {
1794                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1795                break;
1796            }
1797            case IMMERSIVE_MODE_LOCK_MSG: {
1798                final boolean nextState = (msg.arg1 != 0);
1799                if (mUpdateLock.isHeld() != nextState) {
1800                    if (DEBUG_IMMERSIVE) {
1801                        final ActivityRecord r = (ActivityRecord) msg.obj;
1802                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1803                    }
1804                    if (nextState) {
1805                        mUpdateLock.acquire();
1806                    } else {
1807                        mUpdateLock.release();
1808                    }
1809                }
1810                break;
1811            }
1812            case PERSIST_URI_GRANTS_MSG: {
1813                writeGrantedUriPermissions();
1814                break;
1815            }
1816            case REQUEST_ALL_PSS_MSG: {
1817                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1818                break;
1819            }
1820            case START_PROFILES_MSG: {
1821                synchronized (ActivityManagerService.this) {
1822                    startProfilesLocked();
1823                }
1824                break;
1825            }
1826            case UPDATE_TIME: {
1827                synchronized (ActivityManagerService.this) {
1828                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1829                        ProcessRecord r = mLruProcesses.get(i);
1830                        if (r.thread != null) {
1831                            try {
1832                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1833                            } catch (RemoteException ex) {
1834                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1835                            }
1836                        }
1837                    }
1838                }
1839                break;
1840            }
1841            case SYSTEM_USER_START_MSG: {
1842                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1843                        Integer.toString(msg.arg1), msg.arg1);
1844                mSystemServiceManager.startUser(msg.arg1);
1845                break;
1846            }
1847            case SYSTEM_USER_CURRENT_MSG: {
1848                mBatteryStatsService.noteEvent(
1849                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1850                        Integer.toString(msg.arg2), msg.arg2);
1851                mBatteryStatsService.noteEvent(
1852                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1853                        Integer.toString(msg.arg1), msg.arg1);
1854                mSystemServiceManager.switchUser(msg.arg1);
1855                mLockToAppRequest.clearPrompt();
1856                break;
1857            }
1858            case ENTER_ANIMATION_COMPLETE_MSG: {
1859                synchronized (ActivityManagerService.this) {
1860                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1861                    if (r != null && r.app != null && r.app.thread != null) {
1862                        try {
1863                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1864                        } catch (RemoteException e) {
1865                        }
1866                    }
1867                }
1868                break;
1869            }
1870            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1871                enableScreenAfterBoot();
1872                break;
1873            }
1874            }
1875        }
1876    };
1877
1878    static final int COLLECT_PSS_BG_MSG = 1;
1879
1880    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1881        @Override
1882        public void handleMessage(Message msg) {
1883            switch (msg.what) {
1884            case COLLECT_PSS_BG_MSG: {
1885                long start = SystemClock.uptimeMillis();
1886                MemInfoReader memInfo = null;
1887                synchronized (ActivityManagerService.this) {
1888                    if (mFullPssPending) {
1889                        mFullPssPending = false;
1890                        memInfo = new MemInfoReader();
1891                    }
1892                }
1893                if (memInfo != null) {
1894                    updateCpuStatsNow();
1895                    long nativeTotalPss = 0;
1896                    synchronized (mProcessCpuThread) {
1897                        final int N = mProcessCpuTracker.countStats();
1898                        for (int j=0; j<N; j++) {
1899                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1900                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1901                                // This is definitely an application process; skip it.
1902                                continue;
1903                            }
1904                            synchronized (mPidsSelfLocked) {
1905                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1906                                    // This is one of our own processes; skip it.
1907                                    continue;
1908                                }
1909                            }
1910                            nativeTotalPss += Debug.getPss(st.pid, null);
1911                        }
1912                    }
1913                    memInfo.readMemInfo();
1914                    synchronized (this) {
1915                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1916                                + (SystemClock.uptimeMillis()-start) + "ms");
1917                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1918                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1919                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1920                                        +memInfo.getSlabSizeKb(),
1921                                nativeTotalPss);
1922                    }
1923                }
1924
1925                int i=0, num=0;
1926                long[] tmp = new long[1];
1927                do {
1928                    ProcessRecord proc;
1929                    int procState;
1930                    int pid;
1931                    synchronized (ActivityManagerService.this) {
1932                        if (i >= mPendingPssProcesses.size()) {
1933                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1934                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1935                            mPendingPssProcesses.clear();
1936                            return;
1937                        }
1938                        proc = mPendingPssProcesses.get(i);
1939                        procState = proc.pssProcState;
1940                        if (proc.thread != null && procState == proc.setProcState) {
1941                            pid = proc.pid;
1942                        } else {
1943                            proc = null;
1944                            pid = 0;
1945                        }
1946                        i++;
1947                    }
1948                    if (proc != null) {
1949                        long pss = Debug.getPss(pid, tmp);
1950                        synchronized (ActivityManagerService.this) {
1951                            if (proc.thread != null && proc.setProcState == procState
1952                                    && proc.pid == pid) {
1953                                num++;
1954                                proc.lastPssTime = SystemClock.uptimeMillis();
1955                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1956                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1957                                        + ": " + pss + " lastPss=" + proc.lastPss
1958                                        + " state=" + ProcessList.makeProcStateString(procState));
1959                                if (proc.initialIdlePss == 0) {
1960                                    proc.initialIdlePss = pss;
1961                                }
1962                                proc.lastPss = pss;
1963                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1964                                    proc.lastCachedPss = pss;
1965                                }
1966                            }
1967                        }
1968                    }
1969                } while (true);
1970            }
1971            }
1972        }
1973    };
1974
1975    /**
1976     * Monitor for package changes and update our internal state.
1977     */
1978    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1979        @Override
1980        public void onPackageRemoved(String packageName, int uid) {
1981            // Remove all tasks with activities in the specified package from the list of recent tasks
1982            synchronized (ActivityManagerService.this) {
1983                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1984                    TaskRecord tr = mRecentTasks.get(i);
1985                    ComponentName cn = tr.intent.getComponent();
1986                    if (cn != null && cn.getPackageName().equals(packageName)) {
1987                        // If the package name matches, remove the task and kill the process
1988                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1989                    }
1990                }
1991            }
1992        }
1993
1994        @Override
1995        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1996            onPackageModified(packageName);
1997            return true;
1998        }
1999
2000        @Override
2001        public void onPackageModified(String packageName) {
2002            final PackageManager pm = mContext.getPackageManager();
2003            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2004                    new ArrayList<Pair<Intent, Integer>>();
2005            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2006            // Copy the list of recent tasks so that we don't hold onto the lock on
2007            // ActivityManagerService for long periods while checking if components exist.
2008            synchronized (ActivityManagerService.this) {
2009                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2010                    TaskRecord tr = mRecentTasks.get(i);
2011                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2012                }
2013            }
2014            // Check the recent tasks and filter out all tasks with components that no longer exist.
2015            Intent tmpI = new Intent();
2016            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2017                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2018                ComponentName cn = p.first.getComponent();
2019                if (cn != null && cn.getPackageName().equals(packageName)) {
2020                    try {
2021                        // Add the task to the list to remove if the component no longer exists
2022                        tmpI.setComponent(cn);
2023                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2024                            tasksToRemove.add(p.second);
2025                        }
2026                    } catch (Exception e) {}
2027                }
2028            }
2029            // Prune all the tasks with removed components from the list of recent tasks
2030            synchronized (ActivityManagerService.this) {
2031                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2032                    // Remove the task but don't kill the process (since other components in that
2033                    // package may still be running and in the background)
2034                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2035                }
2036            }
2037        }
2038
2039        @Override
2040        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2041            // Force stop the specified packages
2042            if (packages != null) {
2043                for (String pkg : packages) {
2044                    synchronized (ActivityManagerService.this) {
2045                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2046                                "finished booting")) {
2047                            return true;
2048                        }
2049                    }
2050                }
2051            }
2052            return false;
2053        }
2054    };
2055
2056    public void setSystemProcess() {
2057        try {
2058            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2059            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2060            ServiceManager.addService("meminfo", new MemBinder(this));
2061            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2062            ServiceManager.addService("dbinfo", new DbBinder(this));
2063            if (MONITOR_CPU_USAGE) {
2064                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2065            }
2066            ServiceManager.addService("permission", new PermissionController(this));
2067
2068            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2069                    "android", STOCK_PM_FLAGS);
2070            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2071
2072            synchronized (this) {
2073                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2074                app.persistent = true;
2075                app.pid = MY_PID;
2076                app.maxAdj = ProcessList.SYSTEM_ADJ;
2077                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2078                mProcessNames.put(app.processName, app.uid, app);
2079                synchronized (mPidsSelfLocked) {
2080                    mPidsSelfLocked.put(app.pid, app);
2081                }
2082                updateLruProcessLocked(app, false, null);
2083                updateOomAdjLocked();
2084            }
2085        } catch (PackageManager.NameNotFoundException e) {
2086            throw new RuntimeException(
2087                    "Unable to find android system package", e);
2088        }
2089    }
2090
2091    public void setWindowManager(WindowManagerService wm) {
2092        mWindowManager = wm;
2093        mStackSupervisor.setWindowManager(wm);
2094    }
2095
2096    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2097        mUsageStatsService = usageStatsManager;
2098    }
2099
2100    public void startObservingNativeCrashes() {
2101        final NativeCrashListener ncl = new NativeCrashListener(this);
2102        ncl.start();
2103    }
2104
2105    public IAppOpsService getAppOpsService() {
2106        return mAppOpsService;
2107    }
2108
2109    static class MemBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        MemBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump meminfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2126        }
2127    }
2128
2129    static class GraphicsBinder extends Binder {
2130        ActivityManagerService mActivityManagerService;
2131        GraphicsBinder(ActivityManagerService activityManagerService) {
2132            mActivityManagerService = activityManagerService;
2133        }
2134
2135        @Override
2136        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2137            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2138                    != PackageManager.PERMISSION_GRANTED) {
2139                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2140                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2141                        + " without permission " + android.Manifest.permission.DUMP);
2142                return;
2143            }
2144
2145            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2146        }
2147    }
2148
2149    static class DbBinder extends Binder {
2150        ActivityManagerService mActivityManagerService;
2151        DbBinder(ActivityManagerService activityManagerService) {
2152            mActivityManagerService = activityManagerService;
2153        }
2154
2155        @Override
2156        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2157            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2158                    != PackageManager.PERMISSION_GRANTED) {
2159                pw.println("Permission Denial: can't dump dbinfo from from pid="
2160                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2161                        + " without permission " + android.Manifest.permission.DUMP);
2162                return;
2163            }
2164
2165            mActivityManagerService.dumpDbInfo(fd, pw, args);
2166        }
2167    }
2168
2169    static class CpuBinder extends Binder {
2170        ActivityManagerService mActivityManagerService;
2171        CpuBinder(ActivityManagerService activityManagerService) {
2172            mActivityManagerService = activityManagerService;
2173        }
2174
2175        @Override
2176        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2177            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2178                    != PackageManager.PERMISSION_GRANTED) {
2179                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2180                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2181                        + " without permission " + android.Manifest.permission.DUMP);
2182                return;
2183            }
2184
2185            synchronized (mActivityManagerService.mProcessCpuThread) {
2186                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2187                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2188                        SystemClock.uptimeMillis()));
2189            }
2190        }
2191    }
2192
2193    public static final class Lifecycle extends SystemService {
2194        private final ActivityManagerService mService;
2195
2196        public Lifecycle(Context context) {
2197            super(context);
2198            mService = new ActivityManagerService(context);
2199        }
2200
2201        @Override
2202        public void onStart() {
2203            mService.start();
2204        }
2205
2206        public ActivityManagerService getService() {
2207            return mService;
2208        }
2209    }
2210
2211    // Note: This method is invoked on the main thread but may need to attach various
2212    // handlers to other threads.  So take care to be explicit about the looper.
2213    public ActivityManagerService(Context systemContext) {
2214        mContext = systemContext;
2215        mFactoryTest = FactoryTest.getMode();
2216        mSystemThread = ActivityThread.currentActivityThread();
2217
2218        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2219
2220        mHandlerThread = new ServiceThread(TAG,
2221                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2222        mHandlerThread.start();
2223        mHandler = new MainHandler(mHandlerThread.getLooper());
2224
2225        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2226                "foreground", BROADCAST_FG_TIMEOUT, false);
2227        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2228                "background", BROADCAST_BG_TIMEOUT, true);
2229        mBroadcastQueues[0] = mFgBroadcastQueue;
2230        mBroadcastQueues[1] = mBgBroadcastQueue;
2231
2232        mServices = new ActiveServices(this);
2233        mProviderMap = new ProviderMap(this);
2234
2235        // TODO: Move creation of battery stats service outside of activity manager service.
2236        File dataDir = Environment.getDataDirectory();
2237        File systemDir = new File(dataDir, "system");
2238        systemDir.mkdirs();
2239        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2240        mBatteryStatsService.getActiveStatistics().readLocked();
2241        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2242        mOnBattery = DEBUG_POWER ? true
2243                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2244        mBatteryStatsService.getActiveStatistics().setCallback(this);
2245
2246        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2247
2248        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2249
2250        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2251
2252        // User 0 is the first and only user that runs at boot.
2253        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2254        mUserLru.add(Integer.valueOf(0));
2255        updateStartedUserArrayLocked();
2256
2257        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2258            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2259
2260        mConfiguration.setToDefaults();
2261        mConfiguration.setLocale(Locale.getDefault());
2262
2263        mConfigurationSeq = mConfiguration.seq = 1;
2264        mProcessCpuTracker.init();
2265
2266        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2267        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2268        mStackSupervisor = new ActivityStackSupervisor(this);
2269        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2270
2271        mProcessCpuThread = new Thread("CpuTracker") {
2272            @Override
2273            public void run() {
2274                while (true) {
2275                    try {
2276                        try {
2277                            synchronized(this) {
2278                                final long now = SystemClock.uptimeMillis();
2279                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2280                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2281                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2282                                //        + ", write delay=" + nextWriteDelay);
2283                                if (nextWriteDelay < nextCpuDelay) {
2284                                    nextCpuDelay = nextWriteDelay;
2285                                }
2286                                if (nextCpuDelay > 0) {
2287                                    mProcessCpuMutexFree.set(true);
2288                                    this.wait(nextCpuDelay);
2289                                }
2290                            }
2291                        } catch (InterruptedException e) {
2292                        }
2293                        updateCpuStatsNow();
2294                    } catch (Exception e) {
2295                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2296                    }
2297                }
2298            }
2299        };
2300
2301        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2302
2303        Watchdog.getInstance().addMonitor(this);
2304        Watchdog.getInstance().addThread(mHandler);
2305    }
2306
2307    public void setSystemServiceManager(SystemServiceManager mgr) {
2308        mSystemServiceManager = mgr;
2309    }
2310
2311    private void start() {
2312        Process.removeAllProcessGroups();
2313        mProcessCpuThread.start();
2314
2315        mBatteryStatsService.publish(mContext);
2316        mAppOpsService.publish(mContext);
2317        Slog.d("AppOps", "AppOpsService published");
2318        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2319    }
2320
2321    public void initPowerManagement() {
2322        mStackSupervisor.initPowerManagement();
2323        mBatteryStatsService.initPowerManagement();
2324    }
2325
2326    @Override
2327    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2328            throws RemoteException {
2329        if (code == SYSPROPS_TRANSACTION) {
2330            // We need to tell all apps about the system property change.
2331            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2332            synchronized(this) {
2333                final int NP = mProcessNames.getMap().size();
2334                for (int ip=0; ip<NP; ip++) {
2335                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2336                    final int NA = apps.size();
2337                    for (int ia=0; ia<NA; ia++) {
2338                        ProcessRecord app = apps.valueAt(ia);
2339                        if (app.thread != null) {
2340                            procs.add(app.thread.asBinder());
2341                        }
2342                    }
2343                }
2344            }
2345
2346            int N = procs.size();
2347            for (int i=0; i<N; i++) {
2348                Parcel data2 = Parcel.obtain();
2349                try {
2350                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2351                } catch (RemoteException e) {
2352                }
2353                data2.recycle();
2354            }
2355        }
2356        try {
2357            return super.onTransact(code, data, reply, flags);
2358        } catch (RuntimeException e) {
2359            // The activity manager only throws security exceptions, so let's
2360            // log all others.
2361            if (!(e instanceof SecurityException)) {
2362                Slog.wtf(TAG, "Activity Manager Crash", e);
2363            }
2364            throw e;
2365        }
2366    }
2367
2368    void updateCpuStats() {
2369        final long now = SystemClock.uptimeMillis();
2370        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2371            return;
2372        }
2373        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2374            synchronized (mProcessCpuThread) {
2375                mProcessCpuThread.notify();
2376            }
2377        }
2378    }
2379
2380    void updateCpuStatsNow() {
2381        synchronized (mProcessCpuThread) {
2382            mProcessCpuMutexFree.set(false);
2383            final long now = SystemClock.uptimeMillis();
2384            boolean haveNewCpuStats = false;
2385
2386            if (MONITOR_CPU_USAGE &&
2387                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2388                mLastCpuTime.set(now);
2389                haveNewCpuStats = true;
2390                mProcessCpuTracker.update();
2391                //Slog.i(TAG, mProcessCpu.printCurrentState());
2392                //Slog.i(TAG, "Total CPU usage: "
2393                //        + mProcessCpu.getTotalCpuPercent() + "%");
2394
2395                // Slog the cpu usage if the property is set.
2396                if ("true".equals(SystemProperties.get("events.cpu"))) {
2397                    int user = mProcessCpuTracker.getLastUserTime();
2398                    int system = mProcessCpuTracker.getLastSystemTime();
2399                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2400                    int irq = mProcessCpuTracker.getLastIrqTime();
2401                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2402                    int idle = mProcessCpuTracker.getLastIdleTime();
2403
2404                    int total = user + system + iowait + irq + softIrq + idle;
2405                    if (total == 0) total = 1;
2406
2407                    EventLog.writeEvent(EventLogTags.CPU,
2408                            ((user+system+iowait+irq+softIrq) * 100) / total,
2409                            (user * 100) / total,
2410                            (system * 100) / total,
2411                            (iowait * 100) / total,
2412                            (irq * 100) / total,
2413                            (softIrq * 100) / total);
2414                }
2415            }
2416
2417            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2418            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2419            synchronized(bstats) {
2420                synchronized(mPidsSelfLocked) {
2421                    if (haveNewCpuStats) {
2422                        if (mOnBattery) {
2423                            int perc = bstats.startAddingCpuLocked();
2424                            int totalUTime = 0;
2425                            int totalSTime = 0;
2426                            final int N = mProcessCpuTracker.countStats();
2427                            for (int i=0; i<N; i++) {
2428                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2429                                if (!st.working) {
2430                                    continue;
2431                                }
2432                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2433                                int otherUTime = (st.rel_utime*perc)/100;
2434                                int otherSTime = (st.rel_stime*perc)/100;
2435                                totalUTime += otherUTime;
2436                                totalSTime += otherSTime;
2437                                if (pr != null) {
2438                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2439                                    if (ps == null || !ps.isActive()) {
2440                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2441                                                pr.info.uid, pr.processName);
2442                                    }
2443                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2444                                            st.rel_stime-otherSTime);
2445                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2446                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2447                                } else {
2448                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2449                                    if (ps == null || !ps.isActive()) {
2450                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2451                                                bstats.mapUid(st.uid), st.name);
2452                                    }
2453                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2454                                            st.rel_stime-otherSTime);
2455                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2456                                }
2457                            }
2458                            bstats.finishAddingCpuLocked(perc, totalUTime,
2459                                    totalSTime, cpuSpeedTimes);
2460                        }
2461                    }
2462                }
2463
2464                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2465                    mLastWriteTime = now;
2466                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2467                }
2468            }
2469        }
2470    }
2471
2472    @Override
2473    public void batteryNeedsCpuUpdate() {
2474        updateCpuStatsNow();
2475    }
2476
2477    @Override
2478    public void batteryPowerChanged(boolean onBattery) {
2479        // When plugging in, update the CPU stats first before changing
2480        // the plug state.
2481        updateCpuStatsNow();
2482        synchronized (this) {
2483            synchronized(mPidsSelfLocked) {
2484                mOnBattery = DEBUG_POWER ? true : onBattery;
2485            }
2486        }
2487    }
2488
2489    /**
2490     * Initialize the application bind args. These are passed to each
2491     * process when the bindApplication() IPC is sent to the process. They're
2492     * lazily setup to make sure the services are running when they're asked for.
2493     */
2494    private HashMap<String, IBinder> getCommonServicesLocked() {
2495        if (mAppBindArgs == null) {
2496            mAppBindArgs = new HashMap<String, IBinder>();
2497
2498            // Setup the application init args
2499            mAppBindArgs.put("package", ServiceManager.getService("package"));
2500            mAppBindArgs.put("window", ServiceManager.getService("window"));
2501            mAppBindArgs.put(Context.ALARM_SERVICE,
2502                    ServiceManager.getService(Context.ALARM_SERVICE));
2503        }
2504        return mAppBindArgs;
2505    }
2506
2507    final void setFocusedActivityLocked(ActivityRecord r) {
2508        if (mFocusedActivity != r) {
2509            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2510            mFocusedActivity = r;
2511            if (r.task != null && r.task.voiceInteractor != null) {
2512                startRunningVoiceLocked();
2513            } else {
2514                finishRunningVoiceLocked();
2515            }
2516            mStackSupervisor.setFocusedStack(r);
2517            if (r != null) {
2518                mWindowManager.setFocusedApp(r.appToken, true);
2519            }
2520            applyUpdateLockStateLocked(r);
2521        }
2522    }
2523
2524    final void clearFocusedActivity(ActivityRecord r) {
2525        if (mFocusedActivity == r) {
2526            mFocusedActivity = null;
2527        }
2528    }
2529
2530    @Override
2531    public void setFocusedStack(int stackId) {
2532        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2533        synchronized (ActivityManagerService.this) {
2534            ActivityStack stack = mStackSupervisor.getStack(stackId);
2535            if (stack != null) {
2536                ActivityRecord r = stack.topRunningActivityLocked(null);
2537                if (r != null) {
2538                    setFocusedActivityLocked(r);
2539                }
2540            }
2541        }
2542    }
2543
2544    @Override
2545    public void notifyActivityDrawn(IBinder token) {
2546        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2547        synchronized (this) {
2548            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2549            if (r != null) {
2550                r.task.stack.notifyActivityDrawnLocked(r);
2551            }
2552        }
2553    }
2554
2555    final void applyUpdateLockStateLocked(ActivityRecord r) {
2556        // Modifications to the UpdateLock state are done on our handler, outside
2557        // the activity manager's locks.  The new state is determined based on the
2558        // state *now* of the relevant activity record.  The object is passed to
2559        // the handler solely for logging detail, not to be consulted/modified.
2560        final boolean nextState = r != null && r.immersive;
2561        mHandler.sendMessage(
2562                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2563    }
2564
2565    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2566        Message msg = Message.obtain();
2567        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2568        msg.obj = r.task.askedCompatMode ? null : r;
2569        mHandler.sendMessage(msg);
2570    }
2571
2572    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2573            String what, Object obj, ProcessRecord srcApp) {
2574        app.lastActivityTime = now;
2575
2576        if (app.activities.size() > 0) {
2577            // Don't want to touch dependent processes that are hosting activities.
2578            return index;
2579        }
2580
2581        int lrui = mLruProcesses.lastIndexOf(app);
2582        if (lrui < 0) {
2583            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2584                    + what + " " + obj + " from " + srcApp);
2585            return index;
2586        }
2587
2588        if (lrui >= index) {
2589            // Don't want to cause this to move dependent processes *back* in the
2590            // list as if they were less frequently used.
2591            return index;
2592        }
2593
2594        if (lrui >= mLruProcessActivityStart) {
2595            // Don't want to touch dependent processes that are hosting activities.
2596            return index;
2597        }
2598
2599        mLruProcesses.remove(lrui);
2600        if (index > 0) {
2601            index--;
2602        }
2603        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2604                + " in LRU list: " + app);
2605        mLruProcesses.add(index, app);
2606        return index;
2607    }
2608
2609    final void removeLruProcessLocked(ProcessRecord app) {
2610        int lrui = mLruProcesses.lastIndexOf(app);
2611        if (lrui >= 0) {
2612            if (lrui <= mLruProcessActivityStart) {
2613                mLruProcessActivityStart--;
2614            }
2615            if (lrui <= mLruProcessServiceStart) {
2616                mLruProcessServiceStart--;
2617            }
2618            mLruProcesses.remove(lrui);
2619        }
2620    }
2621
2622    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2623            ProcessRecord client) {
2624        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2625                || app.treatLikeActivity;
2626        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2627        if (!activityChange && hasActivity) {
2628            // The process has activities, so we are only allowing activity-based adjustments
2629            // to move it.  It should be kept in the front of the list with other
2630            // processes that have activities, and we don't want those to change their
2631            // order except due to activity operations.
2632            return;
2633        }
2634
2635        mLruSeq++;
2636        final long now = SystemClock.uptimeMillis();
2637        app.lastActivityTime = now;
2638
2639        // First a quick reject: if the app is already at the position we will
2640        // put it, then there is nothing to do.
2641        if (hasActivity) {
2642            final int N = mLruProcesses.size();
2643            if (N > 0 && mLruProcesses.get(N-1) == app) {
2644                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2645                return;
2646            }
2647        } else {
2648            if (mLruProcessServiceStart > 0
2649                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2650                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2651                return;
2652            }
2653        }
2654
2655        int lrui = mLruProcesses.lastIndexOf(app);
2656
2657        if (app.persistent && lrui >= 0) {
2658            // We don't care about the position of persistent processes, as long as
2659            // they are in the list.
2660            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2661            return;
2662        }
2663
2664        /* In progress: compute new position first, so we can avoid doing work
2665           if the process is not actually going to move.  Not yet working.
2666        int addIndex;
2667        int nextIndex;
2668        boolean inActivity = false, inService = false;
2669        if (hasActivity) {
2670            // Process has activities, put it at the very tipsy-top.
2671            addIndex = mLruProcesses.size();
2672            nextIndex = mLruProcessServiceStart;
2673            inActivity = true;
2674        } else if (hasService) {
2675            // Process has services, put it at the top of the service list.
2676            addIndex = mLruProcessActivityStart;
2677            nextIndex = mLruProcessServiceStart;
2678            inActivity = true;
2679            inService = true;
2680        } else  {
2681            // Process not otherwise of interest, it goes to the top of the non-service area.
2682            addIndex = mLruProcessServiceStart;
2683            if (client != null) {
2684                int clientIndex = mLruProcesses.lastIndexOf(client);
2685                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2686                        + app);
2687                if (clientIndex >= 0 && addIndex > clientIndex) {
2688                    addIndex = clientIndex;
2689                }
2690            }
2691            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2692        }
2693
2694        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2695                + mLruProcessActivityStart + "): " + app);
2696        */
2697
2698        if (lrui >= 0) {
2699            if (lrui < mLruProcessActivityStart) {
2700                mLruProcessActivityStart--;
2701            }
2702            if (lrui < mLruProcessServiceStart) {
2703                mLruProcessServiceStart--;
2704            }
2705            /*
2706            if (addIndex > lrui) {
2707                addIndex--;
2708            }
2709            if (nextIndex > lrui) {
2710                nextIndex--;
2711            }
2712            */
2713            mLruProcesses.remove(lrui);
2714        }
2715
2716        /*
2717        mLruProcesses.add(addIndex, app);
2718        if (inActivity) {
2719            mLruProcessActivityStart++;
2720        }
2721        if (inService) {
2722            mLruProcessActivityStart++;
2723        }
2724        */
2725
2726        int nextIndex;
2727        if (hasActivity) {
2728            final int N = mLruProcesses.size();
2729            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2730                // Process doesn't have activities, but has clients with
2731                // activities...  move it up, but one below the top (the top
2732                // should always have a real activity).
2733                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2734                mLruProcesses.add(N-1, app);
2735                // To keep it from spamming the LRU list (by making a bunch of clients),
2736                // we will push down any other entries owned by the app.
2737                final int uid = app.info.uid;
2738                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2739                    ProcessRecord subProc = mLruProcesses.get(i);
2740                    if (subProc.info.uid == uid) {
2741                        // We want to push this one down the list.  If the process after
2742                        // it is for the same uid, however, don't do so, because we don't
2743                        // want them internally to be re-ordered.
2744                        if (mLruProcesses.get(i-1).info.uid != uid) {
2745                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2746                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2747                            ProcessRecord tmp = mLruProcesses.get(i);
2748                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2749                            mLruProcesses.set(i-1, tmp);
2750                            i--;
2751                        }
2752                    } else {
2753                        // A gap, we can stop here.
2754                        break;
2755                    }
2756                }
2757            } else {
2758                // Process has activities, put it at the very tipsy-top.
2759                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2760                mLruProcesses.add(app);
2761            }
2762            nextIndex = mLruProcessServiceStart;
2763        } else if (hasService) {
2764            // Process has services, put it at the top of the service list.
2765            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2766            mLruProcesses.add(mLruProcessActivityStart, app);
2767            nextIndex = mLruProcessServiceStart;
2768            mLruProcessActivityStart++;
2769        } else  {
2770            // Process not otherwise of interest, it goes to the top of the non-service area.
2771            int index = mLruProcessServiceStart;
2772            if (client != null) {
2773                // If there is a client, don't allow the process to be moved up higher
2774                // in the list than that client.
2775                int clientIndex = mLruProcesses.lastIndexOf(client);
2776                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2777                        + " when updating " + app);
2778                if (clientIndex <= lrui) {
2779                    // Don't allow the client index restriction to push it down farther in the
2780                    // list than it already is.
2781                    clientIndex = lrui;
2782                }
2783                if (clientIndex >= 0 && index > clientIndex) {
2784                    index = clientIndex;
2785                }
2786            }
2787            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2788            mLruProcesses.add(index, app);
2789            nextIndex = index-1;
2790            mLruProcessActivityStart++;
2791            mLruProcessServiceStart++;
2792        }
2793
2794        // If the app is currently using a content provider or service,
2795        // bump those processes as well.
2796        for (int j=app.connections.size()-1; j>=0; j--) {
2797            ConnectionRecord cr = app.connections.valueAt(j);
2798            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2799                    && cr.binding.service.app != null
2800                    && cr.binding.service.app.lruSeq != mLruSeq
2801                    && !cr.binding.service.app.persistent) {
2802                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2803                        "service connection", cr, app);
2804            }
2805        }
2806        for (int j=app.conProviders.size()-1; j>=0; j--) {
2807            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2808            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2809                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2810                        "provider reference", cpr, app);
2811            }
2812        }
2813    }
2814
2815    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2816        if (uid == Process.SYSTEM_UID) {
2817            // The system gets to run in any process.  If there are multiple
2818            // processes with the same uid, just pick the first (this
2819            // should never happen).
2820            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2821            if (procs == null) return null;
2822            final int N = procs.size();
2823            for (int i = 0; i < N; i++) {
2824                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2825            }
2826        }
2827        ProcessRecord proc = mProcessNames.get(processName, uid);
2828        if (false && proc != null && !keepIfLarge
2829                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2830                && proc.lastCachedPss >= 4000) {
2831            // Turn this condition on to cause killing to happen regularly, for testing.
2832            if (proc.baseProcessTracker != null) {
2833                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2834            }
2835            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2836        } else if (proc != null && !keepIfLarge
2837                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2838                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2839            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2840            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2841                if (proc.baseProcessTracker != null) {
2842                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2843                }
2844                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2845            }
2846        }
2847        return proc;
2848    }
2849
2850    void ensurePackageDexOpt(String packageName) {
2851        IPackageManager pm = AppGlobals.getPackageManager();
2852        try {
2853            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2854                mDidDexOpt = true;
2855            }
2856        } catch (RemoteException e) {
2857        }
2858    }
2859
2860    boolean isNextTransitionForward() {
2861        int transit = mWindowManager.getPendingAppTransition();
2862        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2863                || transit == AppTransition.TRANSIT_TASK_OPEN
2864                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2865    }
2866
2867    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2868            String processName, String abiOverride, int uid, Runnable crashHandler) {
2869        synchronized(this) {
2870            ApplicationInfo info = new ApplicationInfo();
2871            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2872            // For isolated processes, the former contains the parent's uid and the latter the
2873            // actual uid of the isolated process.
2874            // In the special case introduced by this method (which is, starting an isolated
2875            // process directly from the SystemServer without an actual parent app process) the
2876            // closest thing to a parent's uid is SYSTEM_UID.
2877            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2878            // the |isolated| logic in the ProcessRecord constructor.
2879            info.uid = Process.SYSTEM_UID;
2880            info.processName = processName;
2881            info.className = entryPoint;
2882            info.packageName = "android";
2883            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2884                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2885                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2886                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2887                    crashHandler);
2888            return proc != null ? proc.pid : 0;
2889        }
2890    }
2891
2892    final ProcessRecord startProcessLocked(String processName,
2893            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2894            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2895            boolean isolated, boolean keepIfLarge) {
2896        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2897                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2898                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2899                null /* crashHandler */);
2900    }
2901
2902    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2903            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2904            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2905            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2906        long startTime = SystemClock.elapsedRealtime();
2907        ProcessRecord app;
2908        if (!isolated) {
2909            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2910            checkTime(startTime, "startProcess: after getProcessRecord");
2911        } else {
2912            // If this is an isolated process, it can't re-use an existing process.
2913            app = null;
2914        }
2915        // We don't have to do anything more if:
2916        // (1) There is an existing application record; and
2917        // (2) The caller doesn't think it is dead, OR there is no thread
2918        //     object attached to it so we know it couldn't have crashed; and
2919        // (3) There is a pid assigned to it, so it is either starting or
2920        //     already running.
2921        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2922                + " app=" + app + " knownToBeDead=" + knownToBeDead
2923                + " thread=" + (app != null ? app.thread : null)
2924                + " pid=" + (app != null ? app.pid : -1));
2925        if (app != null && app.pid > 0) {
2926            if (!knownToBeDead || app.thread == null) {
2927                // We already have the app running, or are waiting for it to
2928                // come up (we have a pid but not yet its thread), so keep it.
2929                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2930                // If this is a new package in the process, add the package to the list
2931                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2932                checkTime(startTime, "startProcess: done, added package to proc");
2933                return app;
2934            }
2935
2936            // An application record is attached to a previous process,
2937            // clean it up now.
2938            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2939            checkTime(startTime, "startProcess: bad proc running, killing");
2940            Process.killProcessGroup(app.info.uid, app.pid);
2941            handleAppDiedLocked(app, true, true);
2942            checkTime(startTime, "startProcess: done killing old proc");
2943        }
2944
2945        String hostingNameStr = hostingName != null
2946                ? hostingName.flattenToShortString() : null;
2947
2948        if (!isolated) {
2949            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2950                // If we are in the background, then check to see if this process
2951                // is bad.  If so, we will just silently fail.
2952                if (mBadProcesses.get(info.processName, info.uid) != null) {
2953                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2954                            + "/" + info.processName);
2955                    return null;
2956                }
2957            } else {
2958                // When the user is explicitly starting a process, then clear its
2959                // crash count so that we won't make it bad until they see at
2960                // least one crash dialog again, and make the process good again
2961                // if it had been bad.
2962                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2963                        + "/" + info.processName);
2964                mProcessCrashTimes.remove(info.processName, info.uid);
2965                if (mBadProcesses.get(info.processName, info.uid) != null) {
2966                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2967                            UserHandle.getUserId(info.uid), info.uid,
2968                            info.processName);
2969                    mBadProcesses.remove(info.processName, info.uid);
2970                    if (app != null) {
2971                        app.bad = false;
2972                    }
2973                }
2974            }
2975        }
2976
2977        if (app == null) {
2978            checkTime(startTime, "startProcess: creating new process record");
2979            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2980            app.crashHandler = crashHandler;
2981            if (app == null) {
2982                Slog.w(TAG, "Failed making new process record for "
2983                        + processName + "/" + info.uid + " isolated=" + isolated);
2984                return null;
2985            }
2986            mProcessNames.put(processName, app.uid, app);
2987            if (isolated) {
2988                mIsolatedProcesses.put(app.uid, app);
2989            }
2990            checkTime(startTime, "startProcess: done creating new process record");
2991        } else {
2992            // If this is a new package in the process, add the package to the list
2993            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2994            checkTime(startTime, "startProcess: added package to existing proc");
2995        }
2996
2997        // If the system is not ready yet, then hold off on starting this
2998        // process until it is.
2999        if (!mProcessesReady
3000                && !isAllowedWhileBooting(info)
3001                && !allowWhileBooting) {
3002            if (!mProcessesOnHold.contains(app)) {
3003                mProcessesOnHold.add(app);
3004            }
3005            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3006            checkTime(startTime, "startProcess: returning with proc on hold");
3007            return app;
3008        }
3009
3010        checkTime(startTime, "startProcess: stepping in to startProcess");
3011        startProcessLocked(
3012                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3013        checkTime(startTime, "startProcess: done starting proc!");
3014        return (app.pid != 0) ? app : null;
3015    }
3016
3017    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3018        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3019    }
3020
3021    private final void startProcessLocked(ProcessRecord app,
3022            String hostingType, String hostingNameStr) {
3023        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3024                null /* entryPoint */, null /* entryPointArgs */);
3025    }
3026
3027    private final void startProcessLocked(ProcessRecord app, String hostingType,
3028            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3029        long startTime = SystemClock.elapsedRealtime();
3030        if (app.pid > 0 && app.pid != MY_PID) {
3031            checkTime(startTime, "startProcess: removing from pids map");
3032            synchronized (mPidsSelfLocked) {
3033                mPidsSelfLocked.remove(app.pid);
3034                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3035            }
3036            checkTime(startTime, "startProcess: done removing from pids map");
3037            app.setPid(0);
3038        }
3039
3040        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3041                "startProcessLocked removing on hold: " + app);
3042        mProcessesOnHold.remove(app);
3043
3044        checkTime(startTime, "startProcess: starting to update cpu stats");
3045        updateCpuStats();
3046        checkTime(startTime, "startProcess: done updating cpu stats");
3047
3048        try {
3049            int uid = app.uid;
3050
3051            int[] gids = null;
3052            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3053            if (!app.isolated) {
3054                int[] permGids = null;
3055                try {
3056                    checkTime(startTime, "startProcess: getting gids from package manager");
3057                    final PackageManager pm = mContext.getPackageManager();
3058                    permGids = pm.getPackageGids(app.info.packageName);
3059
3060                    if (Environment.isExternalStorageEmulated()) {
3061                        checkTime(startTime, "startProcess: checking external storage perm");
3062                        if (pm.checkPermission(
3063                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3064                                app.info.packageName) == PERMISSION_GRANTED) {
3065                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3066                        } else {
3067                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3068                        }
3069                    }
3070                } catch (PackageManager.NameNotFoundException e) {
3071                    Slog.w(TAG, "Unable to retrieve gids", e);
3072                }
3073
3074                /*
3075                 * Add shared application and profile GIDs so applications can share some
3076                 * resources like shared libraries and access user-wide resources
3077                 */
3078                if (permGids == null) {
3079                    gids = new int[2];
3080                } else {
3081                    gids = new int[permGids.length + 2];
3082                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3083                }
3084                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3085                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3086            }
3087            checkTime(startTime, "startProcess: building args");
3088            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3089                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3090                        && mTopComponent != null
3091                        && app.processName.equals(mTopComponent.getPackageName())) {
3092                    uid = 0;
3093                }
3094                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3095                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3096                    uid = 0;
3097                }
3098            }
3099            int debugFlags = 0;
3100            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3101                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3102                // Also turn on CheckJNI for debuggable apps. It's quite
3103                // awkward to turn on otherwise.
3104                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3105            }
3106            // Run the app in safe mode if its manifest requests so or the
3107            // system is booted in safe mode.
3108            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3109                mSafeMode == true) {
3110                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3111            }
3112            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3113                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3114            }
3115            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3116                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3117            }
3118            if ("1".equals(SystemProperties.get("debug.assert"))) {
3119                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3120            }
3121
3122            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3123            if (requiredAbi == null) {
3124                requiredAbi = Build.SUPPORTED_ABIS[0];
3125            }
3126
3127            // Start the process.  It will either succeed and return a result containing
3128            // the PID of the new process, or else throw a RuntimeException.
3129            boolean isActivityProcess = (entryPoint == null);
3130            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3131            checkTime(startTime, "startProcess: asking zygote to start proc");
3132            Process.ProcessStartResult startResult = Process.start(entryPoint,
3133                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3134                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3135            checkTime(startTime, "startProcess: returned from zygote!");
3136
3137            if (app.isolated) {
3138                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3139            }
3140            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3141            checkTime(startTime, "startProcess: done updating battery stats");
3142
3143            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3144                    UserHandle.getUserId(uid), startResult.pid, uid,
3145                    app.processName, hostingType,
3146                    hostingNameStr != null ? hostingNameStr : "");
3147
3148            if (app.persistent) {
3149                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3150            }
3151
3152            checkTime(startTime, "startProcess: building log message");
3153            StringBuilder buf = mStringBuilder;
3154            buf.setLength(0);
3155            buf.append("Start proc ");
3156            buf.append(app.processName);
3157            if (!isActivityProcess) {
3158                buf.append(" [");
3159                buf.append(entryPoint);
3160                buf.append("]");
3161            }
3162            buf.append(" for ");
3163            buf.append(hostingType);
3164            if (hostingNameStr != null) {
3165                buf.append(" ");
3166                buf.append(hostingNameStr);
3167            }
3168            buf.append(": pid=");
3169            buf.append(startResult.pid);
3170            buf.append(" uid=");
3171            buf.append(uid);
3172            buf.append(" gids={");
3173            if (gids != null) {
3174                for (int gi=0; gi<gids.length; gi++) {
3175                    if (gi != 0) buf.append(", ");
3176                    buf.append(gids[gi]);
3177
3178                }
3179            }
3180            buf.append("}");
3181            if (requiredAbi != null) {
3182                buf.append(" abi=");
3183                buf.append(requiredAbi);
3184            }
3185            Slog.i(TAG, buf.toString());
3186            app.setPid(startResult.pid);
3187            app.usingWrapper = startResult.usingWrapper;
3188            app.removed = false;
3189            app.killedByAm = false;
3190            checkTime(startTime, "startProcess: starting to update pids map");
3191            synchronized (mPidsSelfLocked) {
3192                this.mPidsSelfLocked.put(startResult.pid, app);
3193                if (isActivityProcess) {
3194                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3195                    msg.obj = app;
3196                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3197                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3198                }
3199            }
3200            checkTime(startTime, "startProcess: done updating pids map");
3201        } catch (RuntimeException e) {
3202            // XXX do better error recovery.
3203            app.setPid(0);
3204            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3205            if (app.isolated) {
3206                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3207            }
3208            Slog.e(TAG, "Failure starting process " + app.processName, e);
3209        }
3210    }
3211
3212    void updateUsageStats(ActivityRecord component, boolean resumed) {
3213        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3214        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3215        if (resumed) {
3216            if (mUsageStatsService != null) {
3217                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3218                        System.currentTimeMillis(),
3219                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3220            }
3221            synchronized (stats) {
3222                stats.noteActivityResumedLocked(component.app.uid);
3223            }
3224        } else {
3225            if (mUsageStatsService != null) {
3226                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3227                        System.currentTimeMillis(),
3228                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3229            }
3230            synchronized (stats) {
3231                stats.noteActivityPausedLocked(component.app.uid);
3232            }
3233        }
3234    }
3235
3236    Intent getHomeIntent() {
3237        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3238        intent.setComponent(mTopComponent);
3239        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3240            intent.addCategory(Intent.CATEGORY_HOME);
3241        }
3242        return intent;
3243    }
3244
3245    boolean startHomeActivityLocked(int userId) {
3246        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3247                && mTopAction == null) {
3248            // We are running in factory test mode, but unable to find
3249            // the factory test app, so just sit around displaying the
3250            // error message and don't try to start anything.
3251            return false;
3252        }
3253        Intent intent = getHomeIntent();
3254        ActivityInfo aInfo =
3255            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3256        if (aInfo != null) {
3257            intent.setComponent(new ComponentName(
3258                    aInfo.applicationInfo.packageName, aInfo.name));
3259            // Don't do this if the home app is currently being
3260            // instrumented.
3261            aInfo = new ActivityInfo(aInfo);
3262            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3263            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3264                    aInfo.applicationInfo.uid, true);
3265            if (app == null || app.instrumentationClass == null) {
3266                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3267                mStackSupervisor.startHomeActivity(intent, aInfo);
3268            }
3269        }
3270
3271        return true;
3272    }
3273
3274    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3275        ActivityInfo ai = null;
3276        ComponentName comp = intent.getComponent();
3277        try {
3278            if (comp != null) {
3279                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3280            } else {
3281                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3282                        intent,
3283                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3284                            flags, userId);
3285
3286                if (info != null) {
3287                    ai = info.activityInfo;
3288                }
3289            }
3290        } catch (RemoteException e) {
3291            // ignore
3292        }
3293
3294        return ai;
3295    }
3296
3297    /**
3298     * Starts the "new version setup screen" if appropriate.
3299     */
3300    void startSetupActivityLocked() {
3301        // Only do this once per boot.
3302        if (mCheckedForSetup) {
3303            return;
3304        }
3305
3306        // We will show this screen if the current one is a different
3307        // version than the last one shown, and we are not running in
3308        // low-level factory test mode.
3309        final ContentResolver resolver = mContext.getContentResolver();
3310        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3311                Settings.Global.getInt(resolver,
3312                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3313            mCheckedForSetup = true;
3314
3315            // See if we should be showing the platform update setup UI.
3316            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3317            List<ResolveInfo> ris = mContext.getPackageManager()
3318                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3319
3320            // We don't allow third party apps to replace this.
3321            ResolveInfo ri = null;
3322            for (int i=0; ris != null && i<ris.size(); i++) {
3323                if ((ris.get(i).activityInfo.applicationInfo.flags
3324                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3325                    ri = ris.get(i);
3326                    break;
3327                }
3328            }
3329
3330            if (ri != null) {
3331                String vers = ri.activityInfo.metaData != null
3332                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3333                        : null;
3334                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3335                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3336                            Intent.METADATA_SETUP_VERSION);
3337                }
3338                String lastVers = Settings.Secure.getString(
3339                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3340                if (vers != null && !vers.equals(lastVers)) {
3341                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3342                    intent.setComponent(new ComponentName(
3343                            ri.activityInfo.packageName, ri.activityInfo.name));
3344                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3345                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3346                            null);
3347                }
3348            }
3349        }
3350    }
3351
3352    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3353        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3354    }
3355
3356    void enforceNotIsolatedCaller(String caller) {
3357        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3358            throw new SecurityException("Isolated process not allowed to call " + caller);
3359        }
3360    }
3361
3362    @Override
3363    public int getFrontActivityScreenCompatMode() {
3364        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3365        synchronized (this) {
3366            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3367        }
3368    }
3369
3370    @Override
3371    public void setFrontActivityScreenCompatMode(int mode) {
3372        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3373                "setFrontActivityScreenCompatMode");
3374        synchronized (this) {
3375            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3376        }
3377    }
3378
3379    @Override
3380    public int getPackageScreenCompatMode(String packageName) {
3381        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3382        synchronized (this) {
3383            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3384        }
3385    }
3386
3387    @Override
3388    public void setPackageScreenCompatMode(String packageName, int mode) {
3389        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3390                "setPackageScreenCompatMode");
3391        synchronized (this) {
3392            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3393        }
3394    }
3395
3396    @Override
3397    public boolean getPackageAskScreenCompat(String packageName) {
3398        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3399        synchronized (this) {
3400            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3401        }
3402    }
3403
3404    @Override
3405    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3406        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3407                "setPackageAskScreenCompat");
3408        synchronized (this) {
3409            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3410        }
3411    }
3412
3413    private void dispatchProcessesChanged() {
3414        int N;
3415        synchronized (this) {
3416            N = mPendingProcessChanges.size();
3417            if (mActiveProcessChanges.length < N) {
3418                mActiveProcessChanges = new ProcessChangeItem[N];
3419            }
3420            mPendingProcessChanges.toArray(mActiveProcessChanges);
3421            mAvailProcessChanges.addAll(mPendingProcessChanges);
3422            mPendingProcessChanges.clear();
3423            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3424        }
3425
3426        int i = mProcessObservers.beginBroadcast();
3427        while (i > 0) {
3428            i--;
3429            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3430            if (observer != null) {
3431                try {
3432                    for (int j=0; j<N; j++) {
3433                        ProcessChangeItem item = mActiveProcessChanges[j];
3434                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3435                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3436                                    + item.pid + " uid=" + item.uid + ": "
3437                                    + item.foregroundActivities);
3438                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3439                                    item.foregroundActivities);
3440                        }
3441                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3442                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3443                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3444                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3445                        }
3446                    }
3447                } catch (RemoteException e) {
3448                }
3449            }
3450        }
3451        mProcessObservers.finishBroadcast();
3452    }
3453
3454    private void dispatchProcessDied(int pid, int uid) {
3455        int i = mProcessObservers.beginBroadcast();
3456        while (i > 0) {
3457            i--;
3458            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3459            if (observer != null) {
3460                try {
3461                    observer.onProcessDied(pid, uid);
3462                } catch (RemoteException e) {
3463                }
3464            }
3465        }
3466        mProcessObservers.finishBroadcast();
3467    }
3468
3469    @Override
3470    public final int startActivity(IApplicationThread caller, String callingPackage,
3471            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3472            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3473        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3474            resultWho, requestCode, startFlags, profilerInfo, options,
3475            UserHandle.getCallingUserId());
3476    }
3477
3478    @Override
3479    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3480            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3481            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3482        enforceNotIsolatedCaller("startActivity");
3483        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3484                false, ALLOW_FULL_ONLY, "startActivity", null);
3485        // TODO: Switch to user app stacks here.
3486        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3487                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3488                profilerInfo, null, null, options, userId, null, null);
3489    }
3490
3491    @Override
3492    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3493            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3494            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3495
3496        // This is very dangerous -- it allows you to perform a start activity (including
3497        // permission grants) as any app that may launch one of your own activities.  So
3498        // we will only allow this to be done from activities that are part of the core framework,
3499        // and then only when they are running as the system.
3500        final ActivityRecord sourceRecord;
3501        final int targetUid;
3502        final String targetPackage;
3503        synchronized (this) {
3504            if (resultTo == null) {
3505                throw new SecurityException("Must be called from an activity");
3506            }
3507            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3508            if (sourceRecord == null) {
3509                throw new SecurityException("Called with bad activity token: " + resultTo);
3510            }
3511            if (!sourceRecord.info.packageName.equals("android")) {
3512                throw new SecurityException(
3513                        "Must be called from an activity that is declared in the android package");
3514            }
3515            if (sourceRecord.app == null) {
3516                throw new SecurityException("Called without a process attached to activity");
3517            }
3518            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3519                // This is still okay, as long as this activity is running under the
3520                // uid of the original calling activity.
3521                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3522                    throw new SecurityException(
3523                            "Calling activity in uid " + sourceRecord.app.uid
3524                                    + " must be system uid or original calling uid "
3525                                    + sourceRecord.launchedFromUid);
3526                }
3527            }
3528            targetUid = sourceRecord.launchedFromUid;
3529            targetPackage = sourceRecord.launchedFromPackage;
3530        }
3531
3532        // TODO: Switch to user app stacks here.
3533        try {
3534            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3535                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3536                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3537            return ret;
3538        } catch (SecurityException e) {
3539            // XXX need to figure out how to propagate to original app.
3540            // A SecurityException here is generally actually a fault of the original
3541            // calling activity (such as a fairly granting permissions), so propagate it
3542            // back to them.
3543            /*
3544            StringBuilder msg = new StringBuilder();
3545            msg.append("While launching");
3546            msg.append(intent.toString());
3547            msg.append(": ");
3548            msg.append(e.getMessage());
3549            */
3550            throw e;
3551        }
3552    }
3553
3554    @Override
3555    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3556            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3557            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3558        enforceNotIsolatedCaller("startActivityAndWait");
3559        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3560                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3561        WaitResult res = new WaitResult();
3562        // TODO: Switch to user app stacks here.
3563        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3564                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3565                options, userId, null, null);
3566        return res;
3567    }
3568
3569    @Override
3570    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3571            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3572            int startFlags, Configuration config, Bundle options, int userId) {
3573        enforceNotIsolatedCaller("startActivityWithConfig");
3574        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3575                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3576        // TODO: Switch to user app stacks here.
3577        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3578                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3579                null, null, config, options, userId, null, null);
3580        return ret;
3581    }
3582
3583    @Override
3584    public int startActivityIntentSender(IApplicationThread caller,
3585            IntentSender intent, Intent fillInIntent, String resolvedType,
3586            IBinder resultTo, String resultWho, int requestCode,
3587            int flagsMask, int flagsValues, Bundle options) {
3588        enforceNotIsolatedCaller("startActivityIntentSender");
3589        // Refuse possible leaked file descriptors
3590        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3591            throw new IllegalArgumentException("File descriptors passed in Intent");
3592        }
3593
3594        IIntentSender sender = intent.getTarget();
3595        if (!(sender instanceof PendingIntentRecord)) {
3596            throw new IllegalArgumentException("Bad PendingIntent object");
3597        }
3598
3599        PendingIntentRecord pir = (PendingIntentRecord)sender;
3600
3601        synchronized (this) {
3602            // If this is coming from the currently resumed activity, it is
3603            // effectively saying that app switches are allowed at this point.
3604            final ActivityStack stack = getFocusedStack();
3605            if (stack.mResumedActivity != null &&
3606                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3607                mAppSwitchesAllowedTime = 0;
3608            }
3609        }
3610        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3611                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3612        return ret;
3613    }
3614
3615    @Override
3616    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3617            Intent intent, String resolvedType, IVoiceInteractionSession session,
3618            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3619            Bundle options, int userId) {
3620        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3621                != PackageManager.PERMISSION_GRANTED) {
3622            String msg = "Permission Denial: startVoiceActivity() from pid="
3623                    + Binder.getCallingPid()
3624                    + ", uid=" + Binder.getCallingUid()
3625                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3626            Slog.w(TAG, msg);
3627            throw new SecurityException(msg);
3628        }
3629        if (session == null || interactor == null) {
3630            throw new NullPointerException("null session or interactor");
3631        }
3632        userId = handleIncomingUser(callingPid, callingUid, userId,
3633                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3634        // TODO: Switch to user app stacks here.
3635        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3636                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3637                null, options, userId, null, null);
3638    }
3639
3640    @Override
3641    public boolean startNextMatchingActivity(IBinder callingActivity,
3642            Intent intent, Bundle options) {
3643        // Refuse possible leaked file descriptors
3644        if (intent != null && intent.hasFileDescriptors() == true) {
3645            throw new IllegalArgumentException("File descriptors passed in Intent");
3646        }
3647
3648        synchronized (this) {
3649            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3650            if (r == null) {
3651                ActivityOptions.abort(options);
3652                return false;
3653            }
3654            if (r.app == null || r.app.thread == null) {
3655                // The caller is not running...  d'oh!
3656                ActivityOptions.abort(options);
3657                return false;
3658            }
3659            intent = new Intent(intent);
3660            // The caller is not allowed to change the data.
3661            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3662            // And we are resetting to find the next component...
3663            intent.setComponent(null);
3664
3665            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3666
3667            ActivityInfo aInfo = null;
3668            try {
3669                List<ResolveInfo> resolves =
3670                    AppGlobals.getPackageManager().queryIntentActivities(
3671                            intent, r.resolvedType,
3672                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3673                            UserHandle.getCallingUserId());
3674
3675                // Look for the original activity in the list...
3676                final int N = resolves != null ? resolves.size() : 0;
3677                for (int i=0; i<N; i++) {
3678                    ResolveInfo rInfo = resolves.get(i);
3679                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3680                            && rInfo.activityInfo.name.equals(r.info.name)) {
3681                        // We found the current one...  the next matching is
3682                        // after it.
3683                        i++;
3684                        if (i<N) {
3685                            aInfo = resolves.get(i).activityInfo;
3686                        }
3687                        if (debug) {
3688                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3689                                    + "/" + r.info.name);
3690                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3691                                    + "/" + aInfo.name);
3692                        }
3693                        break;
3694                    }
3695                }
3696            } catch (RemoteException e) {
3697            }
3698
3699            if (aInfo == null) {
3700                // Nobody who is next!
3701                ActivityOptions.abort(options);
3702                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3703                return false;
3704            }
3705
3706            intent.setComponent(new ComponentName(
3707                    aInfo.applicationInfo.packageName, aInfo.name));
3708            intent.setFlags(intent.getFlags()&~(
3709                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3710                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3711                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3712                    Intent.FLAG_ACTIVITY_NEW_TASK));
3713
3714            // Okay now we need to start the new activity, replacing the
3715            // currently running activity.  This is a little tricky because
3716            // we want to start the new one as if the current one is finished,
3717            // but not finish the current one first so that there is no flicker.
3718            // And thus...
3719            final boolean wasFinishing = r.finishing;
3720            r.finishing = true;
3721
3722            // Propagate reply information over to the new activity.
3723            final ActivityRecord resultTo = r.resultTo;
3724            final String resultWho = r.resultWho;
3725            final int requestCode = r.requestCode;
3726            r.resultTo = null;
3727            if (resultTo != null) {
3728                resultTo.removeResultsLocked(r, resultWho, requestCode);
3729            }
3730
3731            final long origId = Binder.clearCallingIdentity();
3732            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3733                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3734                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3735                    options, false, null, null, null);
3736            Binder.restoreCallingIdentity(origId);
3737
3738            r.finishing = wasFinishing;
3739            if (res != ActivityManager.START_SUCCESS) {
3740                return false;
3741            }
3742            return true;
3743        }
3744    }
3745
3746    @Override
3747    public final int startActivityFromRecents(int taskId, Bundle options) {
3748        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3749            String msg = "Permission Denial: startActivityFromRecents called without " +
3750                    START_TASKS_FROM_RECENTS;
3751            Slog.w(TAG, msg);
3752            throw new SecurityException(msg);
3753        }
3754        return startActivityFromRecentsInner(taskId, options);
3755    }
3756
3757    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3758        final TaskRecord task;
3759        final int callingUid;
3760        final String callingPackage;
3761        final Intent intent;
3762        final int userId;
3763        synchronized (this) {
3764            task = recentTaskForIdLocked(taskId);
3765            if (task == null) {
3766                throw new IllegalArgumentException("Task " + taskId + " not found.");
3767            }
3768            callingUid = task.mCallingUid;
3769            callingPackage = task.mCallingPackage;
3770            intent = task.intent;
3771            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3772            userId = task.userId;
3773        }
3774        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3775                options, userId, null, task);
3776    }
3777
3778    final int startActivityInPackage(int uid, String callingPackage,
3779            Intent intent, String resolvedType, IBinder resultTo,
3780            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3781            IActivityContainer container, TaskRecord inTask) {
3782
3783        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3784                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3785
3786        // TODO: Switch to user app stacks here.
3787        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3788                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3789                null, null, null, options, userId, container, inTask);
3790        return ret;
3791    }
3792
3793    @Override
3794    public final int startActivities(IApplicationThread caller, String callingPackage,
3795            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3796            int userId) {
3797        enforceNotIsolatedCaller("startActivities");
3798        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3799                false, ALLOW_FULL_ONLY, "startActivity", null);
3800        // TODO: Switch to user app stacks here.
3801        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3802                resolvedTypes, resultTo, options, userId);
3803        return ret;
3804    }
3805
3806    final int startActivitiesInPackage(int uid, String callingPackage,
3807            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3808            Bundle options, int userId) {
3809
3810        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3811                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3812        // TODO: Switch to user app stacks here.
3813        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3814                resultTo, options, userId);
3815        return ret;
3816    }
3817
3818    //explicitly remove thd old information in mRecentTasks when removing existing user.
3819    private void removeRecentTasksForUserLocked(int userId) {
3820        if(userId <= 0) {
3821            Slog.i(TAG, "Can't remove recent task on user " + userId);
3822            return;
3823        }
3824
3825        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3826            TaskRecord tr = mRecentTasks.get(i);
3827            if (tr.userId == userId) {
3828                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3829                        + " when finishing user" + userId);
3830                mRecentTasks.remove(i);
3831                tr.removedFromRecents(mTaskPersister);
3832            }
3833        }
3834
3835        // Remove tasks from persistent storage.
3836        mTaskPersister.wakeup(null, true);
3837    }
3838
3839    /**
3840     * Update the recent tasks lists: make sure tasks should still be here (their
3841     * applications / activities still exist), update their availability, fixup ordering
3842     * of affiliations.
3843     */
3844    void cleanupRecentTasksLocked(int userId) {
3845        if (mRecentTasks == null) {
3846            // Happens when called from the packagemanager broadcast before boot.
3847            return;
3848        }
3849
3850        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3851        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3852        final IPackageManager pm = AppGlobals.getPackageManager();
3853        final ActivityInfo dummyAct = new ActivityInfo();
3854        final ApplicationInfo dummyApp = new ApplicationInfo();
3855
3856        int N = mRecentTasks.size();
3857
3858        int[] users = userId == UserHandle.USER_ALL
3859                ? getUsersLocked() : new int[] { userId };
3860        for (int user : users) {
3861            for (int i = 0; i < N; i++) {
3862                TaskRecord task = mRecentTasks.get(i);
3863                if (task.userId != user) {
3864                    // Only look at tasks for the user ID of interest.
3865                    continue;
3866                }
3867                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3868                    // This situation is broken, and we should just get rid of it now.
3869                    mRecentTasks.remove(i);
3870                    task.removedFromRecents(mTaskPersister);
3871                    i--;
3872                    N--;
3873                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3874                    continue;
3875                }
3876                // Check whether this activity is currently available.
3877                if (task.realActivity != null) {
3878                    ActivityInfo ai = availActCache.get(task.realActivity);
3879                    if (ai == null) {
3880                        try {
3881                            ai = pm.getActivityInfo(task.realActivity,
3882                                    PackageManager.GET_UNINSTALLED_PACKAGES
3883                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3884                        } catch (RemoteException e) {
3885                            // Will never happen.
3886                            continue;
3887                        }
3888                        if (ai == null) {
3889                            ai = dummyAct;
3890                        }
3891                        availActCache.put(task.realActivity, ai);
3892                    }
3893                    if (ai == dummyAct) {
3894                        // This could be either because the activity no longer exists, or the
3895                        // app is temporarily gone.  For the former we want to remove the recents
3896                        // entry; for the latter we want to mark it as unavailable.
3897                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3898                        if (app == null) {
3899                            try {
3900                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3901                                        PackageManager.GET_UNINSTALLED_PACKAGES
3902                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3903                            } catch (RemoteException e) {
3904                                // Will never happen.
3905                                continue;
3906                            }
3907                            if (app == null) {
3908                                app = dummyApp;
3909                            }
3910                            availAppCache.put(task.realActivity.getPackageName(), app);
3911                        }
3912                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3913                            // Doesn't exist any more!  Good-bye.
3914                            mRecentTasks.remove(i);
3915                            task.removedFromRecents(mTaskPersister);
3916                            i--;
3917                            N--;
3918                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3919                            continue;
3920                        } else {
3921                            // Otherwise just not available for now.
3922                            if (task.isAvailable) {
3923                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3924                                        + task);
3925                            }
3926                            task.isAvailable = false;
3927                        }
3928                    } else {
3929                        if (!ai.enabled || !ai.applicationInfo.enabled
3930                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3931                            if (task.isAvailable) {
3932                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3933                                        + task + " (enabled=" + ai.enabled + "/"
3934                                        + ai.applicationInfo.enabled +  " flags="
3935                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3936                            }
3937                            task.isAvailable = false;
3938                        } else {
3939                            if (!task.isAvailable) {
3940                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3941                                        + task);
3942                            }
3943                            task.isAvailable = true;
3944                        }
3945                    }
3946                }
3947            }
3948        }
3949
3950        // Verify the affiliate chain for each task.
3951        for (int i = 0; i < N; ) {
3952            TaskRecord task = mRecentTasks.remove(i);
3953            if (mTmpRecents.contains(task)) {
3954                continue;
3955            }
3956            int affiliatedTaskId = task.mAffiliatedTaskId;
3957            while (true) {
3958                TaskRecord next = task.mNextAffiliate;
3959                if (next == null) {
3960                    break;
3961                }
3962                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3963                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3964                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3965                    task.setNextAffiliate(null);
3966                    if (next.mPrevAffiliate == task) {
3967                        next.setPrevAffiliate(null);
3968                    }
3969                    break;
3970                }
3971                if (next.mPrevAffiliate != task) {
3972                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3973                            next.mPrevAffiliate + " task=" + task);
3974                    next.setPrevAffiliate(null);
3975                    task.setNextAffiliate(null);
3976                    break;
3977                }
3978                if (!mRecentTasks.contains(next)) {
3979                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3980                    task.setNextAffiliate(null);
3981                    // We know that next.mPrevAffiliate is always task, from above, so clear
3982                    // its previous affiliate.
3983                    next.setPrevAffiliate(null);
3984                    break;
3985                }
3986                task = next;
3987            }
3988            // task is now the end of the list
3989            do {
3990                mRecentTasks.remove(task);
3991                mRecentTasks.add(i++, task);
3992                mTmpRecents.add(task);
3993                task.inRecents = true;
3994            } while ((task = task.mPrevAffiliate) != null);
3995        }
3996        mTmpRecents.clear();
3997        // mRecentTasks is now in sorted, affiliated order.
3998    }
3999
4000    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4001        int N = mRecentTasks.size();
4002        TaskRecord top = task;
4003        int topIndex = taskIndex;
4004        while (top.mNextAffiliate != null && topIndex > 0) {
4005            top = top.mNextAffiliate;
4006            topIndex--;
4007        }
4008        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4009                + topIndex + " from intial " + taskIndex);
4010        // Find the end of the chain, doing a sanity check along the way.
4011        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4012        int endIndex = topIndex;
4013        TaskRecord prev = top;
4014        while (endIndex < N) {
4015            TaskRecord cur = mRecentTasks.get(endIndex);
4016            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4017                    + endIndex + " " + cur);
4018            if (cur == top) {
4019                // Verify start of the chain.
4020                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4021                    Slog.wtf(TAG, "Bad chain @" + endIndex
4022                            + ": first task has next affiliate: " + prev);
4023                    sane = false;
4024                    break;
4025                }
4026            } else {
4027                // Verify middle of the chain's next points back to the one before.
4028                if (cur.mNextAffiliate != prev
4029                        || cur.mNextAffiliateTaskId != prev.taskId) {
4030                    Slog.wtf(TAG, "Bad chain @" + endIndex
4031                            + ": middle task " + cur + " @" + endIndex
4032                            + " has bad next affiliate "
4033                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4034                            + ", expected " + prev);
4035                    sane = false;
4036                    break;
4037                }
4038            }
4039            if (cur.mPrevAffiliateTaskId == -1) {
4040                // Chain ends here.
4041                if (cur.mPrevAffiliate != null) {
4042                    Slog.wtf(TAG, "Bad chain @" + endIndex
4043                            + ": last task " + cur + " has previous affiliate "
4044                            + cur.mPrevAffiliate);
4045                    sane = false;
4046                }
4047                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4048                break;
4049            } else {
4050                // Verify middle of the chain's prev points to a valid item.
4051                if (cur.mPrevAffiliate == null) {
4052                    Slog.wtf(TAG, "Bad chain @" + endIndex
4053                            + ": task " + cur + " has previous affiliate "
4054                            + cur.mPrevAffiliate + " but should be id "
4055                            + cur.mPrevAffiliate);
4056                    sane = false;
4057                    break;
4058                }
4059            }
4060            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4061                Slog.wtf(TAG, "Bad chain @" + endIndex
4062                        + ": task " + cur + " has affiliated id "
4063                        + cur.mAffiliatedTaskId + " but should be "
4064                        + task.mAffiliatedTaskId);
4065                sane = false;
4066                break;
4067            }
4068            prev = cur;
4069            endIndex++;
4070            if (endIndex >= N) {
4071                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4072                        + ": last task " + prev);
4073                sane = false;
4074                break;
4075            }
4076        }
4077        if (sane) {
4078            if (endIndex < taskIndex) {
4079                Slog.wtf(TAG, "Bad chain @" + endIndex
4080                        + ": did not extend to task " + task + " @" + taskIndex);
4081                sane = false;
4082            }
4083        }
4084        if (sane) {
4085            // All looks good, we can just move all of the affiliated tasks
4086            // to the top.
4087            for (int i=topIndex; i<=endIndex; i++) {
4088                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4089                        + " from " + i + " to " + (i-topIndex));
4090                TaskRecord cur = mRecentTasks.remove(i);
4091                mRecentTasks.add(i-topIndex, cur);
4092            }
4093            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4094                    + " to " + endIndex);
4095            return true;
4096        }
4097
4098        // Whoops, couldn't do it.
4099        return false;
4100    }
4101
4102    final void addRecentTaskLocked(TaskRecord task) {
4103        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4104                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4105
4106        int N = mRecentTasks.size();
4107        // Quick case: check if the top-most recent task is the same.
4108        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4109            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4110            return;
4111        }
4112        // Another quick case: check if this is part of a set of affiliated
4113        // tasks that are at the top.
4114        if (isAffiliated && N > 0 && task.inRecents
4115                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4116            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4117                    + " at top when adding " + task);
4118            return;
4119        }
4120        // Another quick case: never add voice sessions.
4121        if (task.voiceSession != null) {
4122            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4123            return;
4124        }
4125
4126        boolean needAffiliationFix = false;
4127
4128        // Slightly less quick case: the task is already in recents, so all we need
4129        // to do is move it.
4130        if (task.inRecents) {
4131            int taskIndex = mRecentTasks.indexOf(task);
4132            if (taskIndex >= 0) {
4133                if (!isAffiliated) {
4134                    // Simple case: this is not an affiliated task, so we just move it to the front.
4135                    mRecentTasks.remove(taskIndex);
4136                    mRecentTasks.add(0, task);
4137                    notifyTaskPersisterLocked(task, false);
4138                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4139                            + " from " + taskIndex);
4140                    return;
4141                } else {
4142                    // More complicated: need to keep all affiliated tasks together.
4143                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4144                        // All went well.
4145                        return;
4146                    }
4147
4148                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4149                    // everything and then go through our general path of adding a new task.
4150                    needAffiliationFix = true;
4151                }
4152            } else {
4153                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4154                needAffiliationFix = true;
4155            }
4156        }
4157
4158        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4159        trimRecentsForTask(task, true);
4160
4161        N = mRecentTasks.size();
4162        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4163            final TaskRecord tr = mRecentTasks.remove(N - 1);
4164            tr.removedFromRecents(mTaskPersister);
4165            N--;
4166        }
4167        task.inRecents = true;
4168        if (!isAffiliated || needAffiliationFix) {
4169            // If this is a simple non-affiliated task, or we had some failure trying to
4170            // handle it as part of an affilated task, then just place it at the top.
4171            mRecentTasks.add(0, task);
4172        } else if (isAffiliated) {
4173            // If this is a new affiliated task, then move all of the affiliated tasks
4174            // to the front and insert this new one.
4175            TaskRecord other = task.mNextAffiliate;
4176            if (other == null) {
4177                other = task.mPrevAffiliate;
4178            }
4179            if (other != null) {
4180                int otherIndex = mRecentTasks.indexOf(other);
4181                if (otherIndex >= 0) {
4182                    // Insert new task at appropriate location.
4183                    int taskIndex;
4184                    if (other == task.mNextAffiliate) {
4185                        // We found the index of our next affiliation, which is who is
4186                        // before us in the list, so add after that point.
4187                        taskIndex = otherIndex+1;
4188                    } else {
4189                        // We found the index of our previous affiliation, which is who is
4190                        // after us in the list, so add at their position.
4191                        taskIndex = otherIndex;
4192                    }
4193                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4194                            + taskIndex + ": " + task);
4195                    mRecentTasks.add(taskIndex, task);
4196
4197                    // Now move everything to the front.
4198                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4199                        // All went well.
4200                        return;
4201                    }
4202
4203                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4204                    // everything and then go through our general path of adding a new task.
4205                    needAffiliationFix = true;
4206                } else {
4207                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4208                            + other);
4209                    needAffiliationFix = true;
4210                }
4211            } else {
4212                if (DEBUG_RECENTS) Slog.d(TAG,
4213                        "addRecent: adding affiliated task without next/prev:" + task);
4214                needAffiliationFix = true;
4215            }
4216        }
4217        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4218
4219        if (needAffiliationFix) {
4220            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4221            cleanupRecentTasksLocked(task.userId);
4222        }
4223    }
4224
4225    /**
4226     * If needed, remove oldest existing entries in recents that are for the same kind
4227     * of task as the given one.
4228     */
4229    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4230        int N = mRecentTasks.size();
4231        final Intent intent = task.intent;
4232        final boolean document = intent != null && intent.isDocument();
4233
4234        int maxRecents = task.maxRecents - 1;
4235        for (int i=0; i<N; i++) {
4236            final TaskRecord tr = mRecentTasks.get(i);
4237            if (task != tr) {
4238                if (task.userId != tr.userId) {
4239                    continue;
4240                }
4241                if (i > MAX_RECENT_BITMAPS) {
4242                    tr.freeLastThumbnail();
4243                }
4244                final Intent trIntent = tr.intent;
4245                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4246                    (intent == null || !intent.filterEquals(trIntent))) {
4247                    continue;
4248                }
4249                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4250                if (document && trIsDocument) {
4251                    // These are the same document activity (not necessarily the same doc).
4252                    if (maxRecents > 0) {
4253                        --maxRecents;
4254                        continue;
4255                    }
4256                    // Hit the maximum number of documents for this task. Fall through
4257                    // and remove this document from recents.
4258                } else if (document || trIsDocument) {
4259                    // Only one of these is a document. Not the droid we're looking for.
4260                    continue;
4261                }
4262            }
4263
4264            if (!doTrim) {
4265                // If the caller is not actually asking for a trim, just tell them we reached
4266                // a point where the trim would happen.
4267                return i;
4268            }
4269
4270            // Either task and tr are the same or, their affinities match or their intents match
4271            // and neither of them is a document, or they are documents using the same activity
4272            // and their maxRecents has been reached.
4273            tr.disposeThumbnail();
4274            mRecentTasks.remove(i);
4275            if (task != tr) {
4276                tr.removedFromRecents(mTaskPersister);
4277            }
4278            i--;
4279            N--;
4280            if (task.intent == null) {
4281                // If the new recent task we are adding is not fully
4282                // specified, then replace it with the existing recent task.
4283                task = tr;
4284            }
4285            notifyTaskPersisterLocked(tr, false);
4286        }
4287
4288        return -1;
4289    }
4290
4291    @Override
4292    public void reportActivityFullyDrawn(IBinder token) {
4293        synchronized (this) {
4294            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4295            if (r == null) {
4296                return;
4297            }
4298            r.reportFullyDrawnLocked();
4299        }
4300    }
4301
4302    @Override
4303    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4304        synchronized (this) {
4305            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4306            if (r == null) {
4307                return;
4308            }
4309            final long origId = Binder.clearCallingIdentity();
4310            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4311            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4312                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4313            if (config != null) {
4314                r.frozenBeforeDestroy = true;
4315                if (!updateConfigurationLocked(config, r, false, false)) {
4316                    mStackSupervisor.resumeTopActivitiesLocked();
4317                }
4318            }
4319            Binder.restoreCallingIdentity(origId);
4320        }
4321    }
4322
4323    @Override
4324    public int getRequestedOrientation(IBinder token) {
4325        synchronized (this) {
4326            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4327            if (r == null) {
4328                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4329            }
4330            return mWindowManager.getAppOrientation(r.appToken);
4331        }
4332    }
4333
4334    /**
4335     * This is the internal entry point for handling Activity.finish().
4336     *
4337     * @param token The Binder token referencing the Activity we want to finish.
4338     * @param resultCode Result code, if any, from this Activity.
4339     * @param resultData Result data (Intent), if any, from this Activity.
4340     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4341     *            the root Activity in the task.
4342     *
4343     * @return Returns true if the activity successfully finished, or false if it is still running.
4344     */
4345    @Override
4346    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4347            boolean finishTask) {
4348        // Refuse possible leaked file descriptors
4349        if (resultData != null && resultData.hasFileDescriptors() == true) {
4350            throw new IllegalArgumentException("File descriptors passed in Intent");
4351        }
4352
4353        synchronized(this) {
4354            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4355            if (r == null) {
4356                return true;
4357            }
4358            // Keep track of the root activity of the task before we finish it
4359            TaskRecord tr = r.task;
4360            ActivityRecord rootR = tr.getRootActivity();
4361            // Do not allow task to finish in Lock Task mode.
4362            if (tr == mStackSupervisor.mLockTaskModeTask) {
4363                if (rootR == r) {
4364                    mStackSupervisor.showLockTaskToast();
4365                    return false;
4366                }
4367            }
4368            if (mController != null) {
4369                // Find the first activity that is not finishing.
4370                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4371                if (next != null) {
4372                    // ask watcher if this is allowed
4373                    boolean resumeOK = true;
4374                    try {
4375                        resumeOK = mController.activityResuming(next.packageName);
4376                    } catch (RemoteException e) {
4377                        mController = null;
4378                        Watchdog.getInstance().setActivityController(null);
4379                    }
4380
4381                    if (!resumeOK) {
4382                        return false;
4383                    }
4384                }
4385            }
4386            final long origId = Binder.clearCallingIdentity();
4387            try {
4388                boolean res;
4389                if (finishTask && r == rootR) {
4390                    // If requested, remove the task that is associated to this activity only if it
4391                    // was the root activity in the task.  The result code and data is ignored because
4392                    // we don't support returning them across task boundaries.
4393                    res = removeTaskByIdLocked(tr.taskId, 0);
4394                } else {
4395                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4396                            resultData, "app-request", true);
4397                }
4398                return res;
4399            } finally {
4400                Binder.restoreCallingIdentity(origId);
4401            }
4402        }
4403    }
4404
4405    @Override
4406    public final void finishHeavyWeightApp() {
4407        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4408                != PackageManager.PERMISSION_GRANTED) {
4409            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4410                    + Binder.getCallingPid()
4411                    + ", uid=" + Binder.getCallingUid()
4412                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4413            Slog.w(TAG, msg);
4414            throw new SecurityException(msg);
4415        }
4416
4417        synchronized(this) {
4418            if (mHeavyWeightProcess == null) {
4419                return;
4420            }
4421
4422            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4423                    mHeavyWeightProcess.activities);
4424            for (int i=0; i<activities.size(); i++) {
4425                ActivityRecord r = activities.get(i);
4426                if (!r.finishing) {
4427                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4428                            null, "finish-heavy", true);
4429                }
4430            }
4431
4432            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4433                    mHeavyWeightProcess.userId, 0));
4434            mHeavyWeightProcess = null;
4435        }
4436    }
4437
4438    @Override
4439    public void crashApplication(int uid, int initialPid, String packageName,
4440            String message) {
4441        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4442                != PackageManager.PERMISSION_GRANTED) {
4443            String msg = "Permission Denial: crashApplication() from pid="
4444                    + Binder.getCallingPid()
4445                    + ", uid=" + Binder.getCallingUid()
4446                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4447            Slog.w(TAG, msg);
4448            throw new SecurityException(msg);
4449        }
4450
4451        synchronized(this) {
4452            ProcessRecord proc = null;
4453
4454            // Figure out which process to kill.  We don't trust that initialPid
4455            // still has any relation to current pids, so must scan through the
4456            // list.
4457            synchronized (mPidsSelfLocked) {
4458                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4459                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4460                    if (p.uid != uid) {
4461                        continue;
4462                    }
4463                    if (p.pid == initialPid) {
4464                        proc = p;
4465                        break;
4466                    }
4467                    if (p.pkgList.containsKey(packageName)) {
4468                        proc = p;
4469                    }
4470                }
4471            }
4472
4473            if (proc == null) {
4474                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4475                        + " initialPid=" + initialPid
4476                        + " packageName=" + packageName);
4477                return;
4478            }
4479
4480            if (proc.thread != null) {
4481                if (proc.pid == Process.myPid()) {
4482                    Log.w(TAG, "crashApplication: trying to crash self!");
4483                    return;
4484                }
4485                long ident = Binder.clearCallingIdentity();
4486                try {
4487                    proc.thread.scheduleCrash(message);
4488                } catch (RemoteException e) {
4489                }
4490                Binder.restoreCallingIdentity(ident);
4491            }
4492        }
4493    }
4494
4495    @Override
4496    public final void finishSubActivity(IBinder token, String resultWho,
4497            int requestCode) {
4498        synchronized(this) {
4499            final long origId = Binder.clearCallingIdentity();
4500            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4501            if (r != null) {
4502                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4503            }
4504            Binder.restoreCallingIdentity(origId);
4505        }
4506    }
4507
4508    @Override
4509    public boolean finishActivityAffinity(IBinder token) {
4510        synchronized(this) {
4511            final long origId = Binder.clearCallingIdentity();
4512            try {
4513                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4514
4515                ActivityRecord rootR = r.task.getRootActivity();
4516                // Do not allow task to finish in Lock Task mode.
4517                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4518                    if (rootR == r) {
4519                        mStackSupervisor.showLockTaskToast();
4520                        return false;
4521                    }
4522                }
4523                boolean res = false;
4524                if (r != null) {
4525                    res = r.task.stack.finishActivityAffinityLocked(r);
4526                }
4527                return res;
4528            } finally {
4529                Binder.restoreCallingIdentity(origId);
4530            }
4531        }
4532    }
4533
4534    @Override
4535    public void finishVoiceTask(IVoiceInteractionSession session) {
4536        synchronized(this) {
4537            final long origId = Binder.clearCallingIdentity();
4538            try {
4539                mStackSupervisor.finishVoiceTask(session);
4540            } finally {
4541                Binder.restoreCallingIdentity(origId);
4542            }
4543        }
4544
4545    }
4546
4547    @Override
4548    public boolean releaseActivityInstance(IBinder token) {
4549        synchronized(this) {
4550            final long origId = Binder.clearCallingIdentity();
4551            try {
4552                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4553                if (r.task == null || r.task.stack == null) {
4554                    return false;
4555                }
4556                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4557            } finally {
4558                Binder.restoreCallingIdentity(origId);
4559            }
4560        }
4561    }
4562
4563    @Override
4564    public void releaseSomeActivities(IApplicationThread appInt) {
4565        synchronized(this) {
4566            final long origId = Binder.clearCallingIdentity();
4567            try {
4568                ProcessRecord app = getRecordForAppLocked(appInt);
4569                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4570            } finally {
4571                Binder.restoreCallingIdentity(origId);
4572            }
4573        }
4574    }
4575
4576    @Override
4577    public boolean willActivityBeVisible(IBinder token) {
4578        synchronized(this) {
4579            ActivityStack stack = ActivityRecord.getStackLocked(token);
4580            if (stack != null) {
4581                return stack.willActivityBeVisibleLocked(token);
4582            }
4583            return false;
4584        }
4585    }
4586
4587    @Override
4588    public void overridePendingTransition(IBinder token, String packageName,
4589            int enterAnim, int exitAnim) {
4590        synchronized(this) {
4591            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4592            if (self == null) {
4593                return;
4594            }
4595
4596            final long origId = Binder.clearCallingIdentity();
4597
4598            if (self.state == ActivityState.RESUMED
4599                    || self.state == ActivityState.PAUSING) {
4600                mWindowManager.overridePendingAppTransition(packageName,
4601                        enterAnim, exitAnim, null);
4602            }
4603
4604            Binder.restoreCallingIdentity(origId);
4605        }
4606    }
4607
4608    /**
4609     * Main function for removing an existing process from the activity manager
4610     * as a result of that process going away.  Clears out all connections
4611     * to the process.
4612     */
4613    private final void handleAppDiedLocked(ProcessRecord app,
4614            boolean restarting, boolean allowRestart) {
4615        int pid = app.pid;
4616        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4617        if (!restarting) {
4618            removeLruProcessLocked(app);
4619            if (pid > 0) {
4620                ProcessList.remove(pid);
4621            }
4622        }
4623
4624        if (mProfileProc == app) {
4625            clearProfilerLocked();
4626        }
4627
4628        // Remove this application's activities from active lists.
4629        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4630
4631        app.activities.clear();
4632
4633        if (app.instrumentationClass != null) {
4634            Slog.w(TAG, "Crash of app " + app.processName
4635                  + " running instrumentation " + app.instrumentationClass);
4636            Bundle info = new Bundle();
4637            info.putString("shortMsg", "Process crashed.");
4638            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4639        }
4640
4641        if (!restarting) {
4642            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4643                // If there was nothing to resume, and we are not already
4644                // restarting this process, but there is a visible activity that
4645                // is hosted by the process...  then make sure all visible
4646                // activities are running, taking care of restarting this
4647                // process.
4648                if (hasVisibleActivities) {
4649                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4650                }
4651            }
4652        }
4653    }
4654
4655    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4656        IBinder threadBinder = thread.asBinder();
4657        // Find the application record.
4658        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4659            ProcessRecord rec = mLruProcesses.get(i);
4660            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4661                return i;
4662            }
4663        }
4664        return -1;
4665    }
4666
4667    final ProcessRecord getRecordForAppLocked(
4668            IApplicationThread thread) {
4669        if (thread == null) {
4670            return null;
4671        }
4672
4673        int appIndex = getLRURecordIndexForAppLocked(thread);
4674        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4675    }
4676
4677    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4678        // If there are no longer any background processes running,
4679        // and the app that died was not running instrumentation,
4680        // then tell everyone we are now low on memory.
4681        boolean haveBg = false;
4682        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4683            ProcessRecord rec = mLruProcesses.get(i);
4684            if (rec.thread != null
4685                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4686                haveBg = true;
4687                break;
4688            }
4689        }
4690
4691        if (!haveBg) {
4692            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4693            if (doReport) {
4694                long now = SystemClock.uptimeMillis();
4695                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4696                    doReport = false;
4697                } else {
4698                    mLastMemUsageReportTime = now;
4699                }
4700            }
4701            final ArrayList<ProcessMemInfo> memInfos
4702                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4703            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4704            long now = SystemClock.uptimeMillis();
4705            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4706                ProcessRecord rec = mLruProcesses.get(i);
4707                if (rec == dyingProc || rec.thread == null) {
4708                    continue;
4709                }
4710                if (doReport) {
4711                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4712                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4713                }
4714                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4715                    // The low memory report is overriding any current
4716                    // state for a GC request.  Make sure to do
4717                    // heavy/important/visible/foreground processes first.
4718                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4719                        rec.lastRequestedGc = 0;
4720                    } else {
4721                        rec.lastRequestedGc = rec.lastLowMemory;
4722                    }
4723                    rec.reportLowMemory = true;
4724                    rec.lastLowMemory = now;
4725                    mProcessesToGc.remove(rec);
4726                    addProcessToGcListLocked(rec);
4727                }
4728            }
4729            if (doReport) {
4730                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4731                mHandler.sendMessage(msg);
4732            }
4733            scheduleAppGcsLocked();
4734        }
4735    }
4736
4737    final void appDiedLocked(ProcessRecord app) {
4738       appDiedLocked(app, app.pid, app.thread);
4739    }
4740
4741    final void appDiedLocked(ProcessRecord app, int pid,
4742            IApplicationThread thread) {
4743
4744        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4745        synchronized (stats) {
4746            stats.noteProcessDiedLocked(app.info.uid, pid);
4747        }
4748
4749        Process.killProcessGroup(app.info.uid, pid);
4750
4751        // Clean up already done if the process has been re-started.
4752        if (app.pid == pid && app.thread != null &&
4753                app.thread.asBinder() == thread.asBinder()) {
4754            boolean doLowMem = app.instrumentationClass == null;
4755            boolean doOomAdj = doLowMem;
4756            if (!app.killedByAm) {
4757                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4758                        + ") has died.");
4759                mAllowLowerMemLevel = true;
4760            } else {
4761                // Note that we always want to do oom adj to update our state with the
4762                // new number of procs.
4763                mAllowLowerMemLevel = false;
4764                doLowMem = false;
4765            }
4766            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4767            if (DEBUG_CLEANUP) Slog.v(
4768                TAG, "Dying app: " + app + ", pid: " + pid
4769                + ", thread: " + thread.asBinder());
4770            handleAppDiedLocked(app, false, true);
4771
4772            if (doOomAdj) {
4773                updateOomAdjLocked();
4774            }
4775            if (doLowMem) {
4776                doLowMemReportIfNeededLocked(app);
4777            }
4778        } else if (app.pid != pid) {
4779            // A new process has already been started.
4780            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4781                    + ") has died and restarted (pid " + app.pid + ").");
4782            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4783        } else if (DEBUG_PROCESSES) {
4784            Slog.d(TAG, "Received spurious death notification for thread "
4785                    + thread.asBinder());
4786        }
4787    }
4788
4789    /**
4790     * If a stack trace dump file is configured, dump process stack traces.
4791     * @param clearTraces causes the dump file to be erased prior to the new
4792     *    traces being written, if true; when false, the new traces will be
4793     *    appended to any existing file content.
4794     * @param firstPids of dalvik VM processes to dump stack traces for first
4795     * @param lastPids of dalvik VM processes to dump stack traces for last
4796     * @param nativeProcs optional list of native process names to dump stack crawls
4797     * @return file containing stack traces, or null if no dump file is configured
4798     */
4799    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4800            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4801        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4802        if (tracesPath == null || tracesPath.length() == 0) {
4803            return null;
4804        }
4805
4806        File tracesFile = new File(tracesPath);
4807        try {
4808            File tracesDir = tracesFile.getParentFile();
4809            if (!tracesDir.exists()) {
4810                tracesFile.mkdirs();
4811                if (!SELinux.restorecon(tracesDir)) {
4812                    return null;
4813                }
4814            }
4815            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4816
4817            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4818            tracesFile.createNewFile();
4819            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4820        } catch (IOException e) {
4821            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4822            return null;
4823        }
4824
4825        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4826        return tracesFile;
4827    }
4828
4829    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4830            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4831        // Use a FileObserver to detect when traces finish writing.
4832        // The order of traces is considered important to maintain for legibility.
4833        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4834            @Override
4835            public synchronized void onEvent(int event, String path) { notify(); }
4836        };
4837
4838        try {
4839            observer.startWatching();
4840
4841            // First collect all of the stacks of the most important pids.
4842            if (firstPids != null) {
4843                try {
4844                    int num = firstPids.size();
4845                    for (int i = 0; i < num; i++) {
4846                        synchronized (observer) {
4847                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4848                            observer.wait(200);  // Wait for write-close, give up after 200msec
4849                        }
4850                    }
4851                } catch (InterruptedException e) {
4852                    Log.wtf(TAG, e);
4853                }
4854            }
4855
4856            // Next collect the stacks of the native pids
4857            if (nativeProcs != null) {
4858                int[] pids = Process.getPidsForCommands(nativeProcs);
4859                if (pids != null) {
4860                    for (int pid : pids) {
4861                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4862                    }
4863                }
4864            }
4865
4866            // Lastly, measure CPU usage.
4867            if (processCpuTracker != null) {
4868                processCpuTracker.init();
4869                System.gc();
4870                processCpuTracker.update();
4871                try {
4872                    synchronized (processCpuTracker) {
4873                        processCpuTracker.wait(500); // measure over 1/2 second.
4874                    }
4875                } catch (InterruptedException e) {
4876                }
4877                processCpuTracker.update();
4878
4879                // We'll take the stack crawls of just the top apps using CPU.
4880                final int N = processCpuTracker.countWorkingStats();
4881                int numProcs = 0;
4882                for (int i=0; i<N && numProcs<5; i++) {
4883                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4884                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4885                        numProcs++;
4886                        try {
4887                            synchronized (observer) {
4888                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4889                                observer.wait(200);  // Wait for write-close, give up after 200msec
4890                            }
4891                        } catch (InterruptedException e) {
4892                            Log.wtf(TAG, e);
4893                        }
4894
4895                    }
4896                }
4897            }
4898        } finally {
4899            observer.stopWatching();
4900        }
4901    }
4902
4903    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4904        if (true || IS_USER_BUILD) {
4905            return;
4906        }
4907        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4908        if (tracesPath == null || tracesPath.length() == 0) {
4909            return;
4910        }
4911
4912        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4913        StrictMode.allowThreadDiskWrites();
4914        try {
4915            final File tracesFile = new File(tracesPath);
4916            final File tracesDir = tracesFile.getParentFile();
4917            final File tracesTmp = new File(tracesDir, "__tmp__");
4918            try {
4919                if (!tracesDir.exists()) {
4920                    tracesFile.mkdirs();
4921                    if (!SELinux.restorecon(tracesDir.getPath())) {
4922                        return;
4923                    }
4924                }
4925                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4926
4927                if (tracesFile.exists()) {
4928                    tracesTmp.delete();
4929                    tracesFile.renameTo(tracesTmp);
4930                }
4931                StringBuilder sb = new StringBuilder();
4932                Time tobj = new Time();
4933                tobj.set(System.currentTimeMillis());
4934                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4935                sb.append(": ");
4936                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4937                sb.append(" since ");
4938                sb.append(msg);
4939                FileOutputStream fos = new FileOutputStream(tracesFile);
4940                fos.write(sb.toString().getBytes());
4941                if (app == null) {
4942                    fos.write("\n*** No application process!".getBytes());
4943                }
4944                fos.close();
4945                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4946            } catch (IOException e) {
4947                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4948                return;
4949            }
4950
4951            if (app != null) {
4952                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4953                firstPids.add(app.pid);
4954                dumpStackTraces(tracesPath, firstPids, null, null, null);
4955            }
4956
4957            File lastTracesFile = null;
4958            File curTracesFile = null;
4959            for (int i=9; i>=0; i--) {
4960                String name = String.format(Locale.US, "slow%02d.txt", i);
4961                curTracesFile = new File(tracesDir, name);
4962                if (curTracesFile.exists()) {
4963                    if (lastTracesFile != null) {
4964                        curTracesFile.renameTo(lastTracesFile);
4965                    } else {
4966                        curTracesFile.delete();
4967                    }
4968                }
4969                lastTracesFile = curTracesFile;
4970            }
4971            tracesFile.renameTo(curTracesFile);
4972            if (tracesTmp.exists()) {
4973                tracesTmp.renameTo(tracesFile);
4974            }
4975        } finally {
4976            StrictMode.setThreadPolicy(oldPolicy);
4977        }
4978    }
4979
4980    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4981            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4982        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4983        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4984
4985        if (mController != null) {
4986            try {
4987                // 0 == continue, -1 = kill process immediately
4988                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4989                if (res < 0 && app.pid != MY_PID) {
4990                    app.kill("anr", true);
4991                }
4992            } catch (RemoteException e) {
4993                mController = null;
4994                Watchdog.getInstance().setActivityController(null);
4995            }
4996        }
4997
4998        long anrTime = SystemClock.uptimeMillis();
4999        if (MONITOR_CPU_USAGE) {
5000            updateCpuStatsNow();
5001        }
5002
5003        synchronized (this) {
5004            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5005            if (mShuttingDown) {
5006                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5007                return;
5008            } else if (app.notResponding) {
5009                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5010                return;
5011            } else if (app.crashing) {
5012                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5013                return;
5014            }
5015
5016            // In case we come through here for the same app before completing
5017            // this one, mark as anring now so we will bail out.
5018            app.notResponding = true;
5019
5020            // Log the ANR to the event log.
5021            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5022                    app.processName, app.info.flags, annotation);
5023
5024            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5025            firstPids.add(app.pid);
5026
5027            int parentPid = app.pid;
5028            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5029            if (parentPid != app.pid) firstPids.add(parentPid);
5030
5031            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5032
5033            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5034                ProcessRecord r = mLruProcesses.get(i);
5035                if (r != null && r.thread != null) {
5036                    int pid = r.pid;
5037                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5038                        if (r.persistent) {
5039                            firstPids.add(pid);
5040                        } else {
5041                            lastPids.put(pid, Boolean.TRUE);
5042                        }
5043                    }
5044                }
5045            }
5046        }
5047
5048        // Log the ANR to the main log.
5049        StringBuilder info = new StringBuilder();
5050        info.setLength(0);
5051        info.append("ANR in ").append(app.processName);
5052        if (activity != null && activity.shortComponentName != null) {
5053            info.append(" (").append(activity.shortComponentName).append(")");
5054        }
5055        info.append("\n");
5056        info.append("PID: ").append(app.pid).append("\n");
5057        if (annotation != null) {
5058            info.append("Reason: ").append(annotation).append("\n");
5059        }
5060        if (parent != null && parent != activity) {
5061            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5062        }
5063
5064        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5065
5066        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5067                NATIVE_STACKS_OF_INTEREST);
5068
5069        String cpuInfo = null;
5070        if (MONITOR_CPU_USAGE) {
5071            updateCpuStatsNow();
5072            synchronized (mProcessCpuThread) {
5073                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5074            }
5075            info.append(processCpuTracker.printCurrentLoad());
5076            info.append(cpuInfo);
5077        }
5078
5079        info.append(processCpuTracker.printCurrentState(anrTime));
5080
5081        Slog.e(TAG, info.toString());
5082        if (tracesFile == null) {
5083            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5084            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5085        }
5086
5087        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5088                cpuInfo, tracesFile, null);
5089
5090        if (mController != null) {
5091            try {
5092                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5093                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5094                if (res != 0) {
5095                    if (res < 0 && app.pid != MY_PID) {
5096                        app.kill("anr", true);
5097                    } else {
5098                        synchronized (this) {
5099                            mServices.scheduleServiceTimeoutLocked(app);
5100                        }
5101                    }
5102                    return;
5103                }
5104            } catch (RemoteException e) {
5105                mController = null;
5106                Watchdog.getInstance().setActivityController(null);
5107            }
5108        }
5109
5110        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5111        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5112                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5113
5114        synchronized (this) {
5115            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5116                app.kill("bg anr", true);
5117                return;
5118            }
5119
5120            // Set the app's notResponding state, and look up the errorReportReceiver
5121            makeAppNotRespondingLocked(app,
5122                    activity != null ? activity.shortComponentName : null,
5123                    annotation != null ? "ANR " + annotation : "ANR",
5124                    info.toString());
5125
5126            // Bring up the infamous App Not Responding dialog
5127            Message msg = Message.obtain();
5128            HashMap<String, Object> map = new HashMap<String, Object>();
5129            msg.what = SHOW_NOT_RESPONDING_MSG;
5130            msg.obj = map;
5131            msg.arg1 = aboveSystem ? 1 : 0;
5132            map.put("app", app);
5133            if (activity != null) {
5134                map.put("activity", activity);
5135            }
5136
5137            mHandler.sendMessage(msg);
5138        }
5139    }
5140
5141    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5142        if (!mLaunchWarningShown) {
5143            mLaunchWarningShown = true;
5144            mHandler.post(new Runnable() {
5145                @Override
5146                public void run() {
5147                    synchronized (ActivityManagerService.this) {
5148                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5149                        d.show();
5150                        mHandler.postDelayed(new Runnable() {
5151                            @Override
5152                            public void run() {
5153                                synchronized (ActivityManagerService.this) {
5154                                    d.dismiss();
5155                                    mLaunchWarningShown = false;
5156                                }
5157                            }
5158                        }, 4000);
5159                    }
5160                }
5161            });
5162        }
5163    }
5164
5165    @Override
5166    public boolean clearApplicationUserData(final String packageName,
5167            final IPackageDataObserver observer, int userId) {
5168        enforceNotIsolatedCaller("clearApplicationUserData");
5169        int uid = Binder.getCallingUid();
5170        int pid = Binder.getCallingPid();
5171        userId = handleIncomingUser(pid, uid,
5172                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5173        long callingId = Binder.clearCallingIdentity();
5174        try {
5175            IPackageManager pm = AppGlobals.getPackageManager();
5176            int pkgUid = -1;
5177            synchronized(this) {
5178                try {
5179                    pkgUid = pm.getPackageUid(packageName, userId);
5180                } catch (RemoteException e) {
5181                }
5182                if (pkgUid == -1) {
5183                    Slog.w(TAG, "Invalid packageName: " + packageName);
5184                    if (observer != null) {
5185                        try {
5186                            observer.onRemoveCompleted(packageName, false);
5187                        } catch (RemoteException e) {
5188                            Slog.i(TAG, "Observer no longer exists.");
5189                        }
5190                    }
5191                    return false;
5192                }
5193                if (uid == pkgUid || checkComponentPermission(
5194                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5195                        pid, uid, -1, true)
5196                        == PackageManager.PERMISSION_GRANTED) {
5197                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5198                } else {
5199                    throw new SecurityException("PID " + pid + " does not have permission "
5200                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5201                                    + " of package " + packageName);
5202                }
5203
5204                // Remove all tasks match the cleared application package and user
5205                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5206                    final TaskRecord tr = mRecentTasks.get(i);
5207                    final String taskPackageName =
5208                            tr.getBaseIntent().getComponent().getPackageName();
5209                    if (tr.userId != userId) continue;
5210                    if (!taskPackageName.equals(packageName)) continue;
5211                    removeTaskByIdLocked(tr.taskId, 0);
5212                }
5213            }
5214
5215            try {
5216                // Clear application user data
5217                pm.clearApplicationUserData(packageName, observer, userId);
5218
5219                synchronized(this) {
5220                    // Remove all permissions granted from/to this package
5221                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5222                }
5223
5224                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5225                        Uri.fromParts("package", packageName, null));
5226                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5227                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5228                        null, null, 0, null, null, null, false, false, userId);
5229            } catch (RemoteException e) {
5230            }
5231        } finally {
5232            Binder.restoreCallingIdentity(callingId);
5233        }
5234        return true;
5235    }
5236
5237    @Override
5238    public void killBackgroundProcesses(final String packageName, int userId) {
5239        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5240                != PackageManager.PERMISSION_GRANTED &&
5241                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5242                        != PackageManager.PERMISSION_GRANTED) {
5243            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5244                    + Binder.getCallingPid()
5245                    + ", uid=" + Binder.getCallingUid()
5246                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5247            Slog.w(TAG, msg);
5248            throw new SecurityException(msg);
5249        }
5250
5251        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5252                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5253        long callingId = Binder.clearCallingIdentity();
5254        try {
5255            IPackageManager pm = AppGlobals.getPackageManager();
5256            synchronized(this) {
5257                int appId = -1;
5258                try {
5259                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5260                } catch (RemoteException e) {
5261                }
5262                if (appId == -1) {
5263                    Slog.w(TAG, "Invalid packageName: " + packageName);
5264                    return;
5265                }
5266                killPackageProcessesLocked(packageName, appId, userId,
5267                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5268            }
5269        } finally {
5270            Binder.restoreCallingIdentity(callingId);
5271        }
5272    }
5273
5274    @Override
5275    public void killAllBackgroundProcesses() {
5276        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5277                != PackageManager.PERMISSION_GRANTED) {
5278            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5279                    + Binder.getCallingPid()
5280                    + ", uid=" + Binder.getCallingUid()
5281                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5282            Slog.w(TAG, msg);
5283            throw new SecurityException(msg);
5284        }
5285
5286        long callingId = Binder.clearCallingIdentity();
5287        try {
5288            synchronized(this) {
5289                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5290                final int NP = mProcessNames.getMap().size();
5291                for (int ip=0; ip<NP; ip++) {
5292                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5293                    final int NA = apps.size();
5294                    for (int ia=0; ia<NA; ia++) {
5295                        ProcessRecord app = apps.valueAt(ia);
5296                        if (app.persistent) {
5297                            // we don't kill persistent processes
5298                            continue;
5299                        }
5300                        if (app.removed) {
5301                            procs.add(app);
5302                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5303                            app.removed = true;
5304                            procs.add(app);
5305                        }
5306                    }
5307                }
5308
5309                int N = procs.size();
5310                for (int i=0; i<N; i++) {
5311                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5312                }
5313                mAllowLowerMemLevel = true;
5314                updateOomAdjLocked();
5315                doLowMemReportIfNeededLocked(null);
5316            }
5317        } finally {
5318            Binder.restoreCallingIdentity(callingId);
5319        }
5320    }
5321
5322    @Override
5323    public void forceStopPackage(final String packageName, int userId) {
5324        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5325                != PackageManager.PERMISSION_GRANTED) {
5326            String msg = "Permission Denial: forceStopPackage() from pid="
5327                    + Binder.getCallingPid()
5328                    + ", uid=" + Binder.getCallingUid()
5329                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5330            Slog.w(TAG, msg);
5331            throw new SecurityException(msg);
5332        }
5333        final int callingPid = Binder.getCallingPid();
5334        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5335                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5336        long callingId = Binder.clearCallingIdentity();
5337        try {
5338            IPackageManager pm = AppGlobals.getPackageManager();
5339            synchronized(this) {
5340                int[] users = userId == UserHandle.USER_ALL
5341                        ? getUsersLocked() : new int[] { userId };
5342                for (int user : users) {
5343                    int pkgUid = -1;
5344                    try {
5345                        pkgUid = pm.getPackageUid(packageName, user);
5346                    } catch (RemoteException e) {
5347                    }
5348                    if (pkgUid == -1) {
5349                        Slog.w(TAG, "Invalid packageName: " + packageName);
5350                        continue;
5351                    }
5352                    try {
5353                        pm.setPackageStoppedState(packageName, true, user);
5354                    } catch (RemoteException e) {
5355                    } catch (IllegalArgumentException e) {
5356                        Slog.w(TAG, "Failed trying to unstop package "
5357                                + packageName + ": " + e);
5358                    }
5359                    if (isUserRunningLocked(user, false)) {
5360                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5361                    }
5362                }
5363            }
5364        } finally {
5365            Binder.restoreCallingIdentity(callingId);
5366        }
5367    }
5368
5369    @Override
5370    public void addPackageDependency(String packageName) {
5371        synchronized (this) {
5372            int callingPid = Binder.getCallingPid();
5373            if (callingPid == Process.myPid()) {
5374                //  Yeah, um, no.
5375                Slog.w(TAG, "Can't addPackageDependency on system process");
5376                return;
5377            }
5378            ProcessRecord proc;
5379            synchronized (mPidsSelfLocked) {
5380                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5381            }
5382            if (proc != null) {
5383                if (proc.pkgDeps == null) {
5384                    proc.pkgDeps = new ArraySet<String>(1);
5385                }
5386                proc.pkgDeps.add(packageName);
5387            }
5388        }
5389    }
5390
5391    /*
5392     * The pkg name and app id have to be specified.
5393     */
5394    @Override
5395    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5396        if (pkg == null) {
5397            return;
5398        }
5399        // Make sure the uid is valid.
5400        if (appid < 0) {
5401            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5402            return;
5403        }
5404        int callerUid = Binder.getCallingUid();
5405        // Only the system server can kill an application
5406        if (callerUid == Process.SYSTEM_UID) {
5407            // Post an aysnc message to kill the application
5408            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5409            msg.arg1 = appid;
5410            msg.arg2 = 0;
5411            Bundle bundle = new Bundle();
5412            bundle.putString("pkg", pkg);
5413            bundle.putString("reason", reason);
5414            msg.obj = bundle;
5415            mHandler.sendMessage(msg);
5416        } else {
5417            throw new SecurityException(callerUid + " cannot kill pkg: " +
5418                    pkg);
5419        }
5420    }
5421
5422    @Override
5423    public void closeSystemDialogs(String reason) {
5424        enforceNotIsolatedCaller("closeSystemDialogs");
5425
5426        final int pid = Binder.getCallingPid();
5427        final int uid = Binder.getCallingUid();
5428        final long origId = Binder.clearCallingIdentity();
5429        try {
5430            synchronized (this) {
5431                // Only allow this from foreground processes, so that background
5432                // applications can't abuse it to prevent system UI from being shown.
5433                if (uid >= Process.FIRST_APPLICATION_UID) {
5434                    ProcessRecord proc;
5435                    synchronized (mPidsSelfLocked) {
5436                        proc = mPidsSelfLocked.get(pid);
5437                    }
5438                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5439                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5440                                + " from background process " + proc);
5441                        return;
5442                    }
5443                }
5444                closeSystemDialogsLocked(reason);
5445            }
5446        } finally {
5447            Binder.restoreCallingIdentity(origId);
5448        }
5449    }
5450
5451    void closeSystemDialogsLocked(String reason) {
5452        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5453        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5454                | Intent.FLAG_RECEIVER_FOREGROUND);
5455        if (reason != null) {
5456            intent.putExtra("reason", reason);
5457        }
5458        mWindowManager.closeSystemDialogs(reason);
5459
5460        mStackSupervisor.closeSystemDialogsLocked();
5461
5462        broadcastIntentLocked(null, null, intent, null,
5463                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5464                Process.SYSTEM_UID, UserHandle.USER_ALL);
5465    }
5466
5467    @Override
5468    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5469        enforceNotIsolatedCaller("getProcessMemoryInfo");
5470        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5471        for (int i=pids.length-1; i>=0; i--) {
5472            ProcessRecord proc;
5473            int oomAdj;
5474            synchronized (this) {
5475                synchronized (mPidsSelfLocked) {
5476                    proc = mPidsSelfLocked.get(pids[i]);
5477                    oomAdj = proc != null ? proc.setAdj : 0;
5478                }
5479            }
5480            infos[i] = new Debug.MemoryInfo();
5481            Debug.getMemoryInfo(pids[i], infos[i]);
5482            if (proc != null) {
5483                synchronized (this) {
5484                    if (proc.thread != null && proc.setAdj == oomAdj) {
5485                        // Record this for posterity if the process has been stable.
5486                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5487                                infos[i].getTotalUss(), false, proc.pkgList);
5488                    }
5489                }
5490            }
5491        }
5492        return infos;
5493    }
5494
5495    @Override
5496    public long[] getProcessPss(int[] pids) {
5497        enforceNotIsolatedCaller("getProcessPss");
5498        long[] pss = new long[pids.length];
5499        for (int i=pids.length-1; i>=0; i--) {
5500            ProcessRecord proc;
5501            int oomAdj;
5502            synchronized (this) {
5503                synchronized (mPidsSelfLocked) {
5504                    proc = mPidsSelfLocked.get(pids[i]);
5505                    oomAdj = proc != null ? proc.setAdj : 0;
5506                }
5507            }
5508            long[] tmpUss = new long[1];
5509            pss[i] = Debug.getPss(pids[i], tmpUss);
5510            if (proc != null) {
5511                synchronized (this) {
5512                    if (proc.thread != null && proc.setAdj == oomAdj) {
5513                        // Record this for posterity if the process has been stable.
5514                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5515                    }
5516                }
5517            }
5518        }
5519        return pss;
5520    }
5521
5522    @Override
5523    public void killApplicationProcess(String processName, int uid) {
5524        if (processName == null) {
5525            return;
5526        }
5527
5528        int callerUid = Binder.getCallingUid();
5529        // Only the system server can kill an application
5530        if (callerUid == Process.SYSTEM_UID) {
5531            synchronized (this) {
5532                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5533                if (app != null && app.thread != null) {
5534                    try {
5535                        app.thread.scheduleSuicide();
5536                    } catch (RemoteException e) {
5537                        // If the other end already died, then our work here is done.
5538                    }
5539                } else {
5540                    Slog.w(TAG, "Process/uid not found attempting kill of "
5541                            + processName + " / " + uid);
5542                }
5543            }
5544        } else {
5545            throw new SecurityException(callerUid + " cannot kill app process: " +
5546                    processName);
5547        }
5548    }
5549
5550    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5551        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5552                false, true, false, false, UserHandle.getUserId(uid), reason);
5553        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5554                Uri.fromParts("package", packageName, null));
5555        if (!mProcessesReady) {
5556            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5557                    | Intent.FLAG_RECEIVER_FOREGROUND);
5558        }
5559        intent.putExtra(Intent.EXTRA_UID, uid);
5560        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5561        broadcastIntentLocked(null, null, intent,
5562                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5563                false, false,
5564                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5565    }
5566
5567    private void forceStopUserLocked(int userId, String reason) {
5568        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5569        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5570        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5571                | Intent.FLAG_RECEIVER_FOREGROUND);
5572        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5573        broadcastIntentLocked(null, null, intent,
5574                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5575                false, false,
5576                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5577    }
5578
5579    private final boolean killPackageProcessesLocked(String packageName, int appId,
5580            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5581            boolean doit, boolean evenPersistent, String reason) {
5582        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5583
5584        // Remove all processes this package may have touched: all with the
5585        // same UID (except for the system or root user), and all whose name
5586        // matches the package name.
5587        final int NP = mProcessNames.getMap().size();
5588        for (int ip=0; ip<NP; ip++) {
5589            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5590            final int NA = apps.size();
5591            for (int ia=0; ia<NA; ia++) {
5592                ProcessRecord app = apps.valueAt(ia);
5593                if (app.persistent && !evenPersistent) {
5594                    // we don't kill persistent processes
5595                    continue;
5596                }
5597                if (app.removed) {
5598                    if (doit) {
5599                        procs.add(app);
5600                    }
5601                    continue;
5602                }
5603
5604                // Skip process if it doesn't meet our oom adj requirement.
5605                if (app.setAdj < minOomAdj) {
5606                    continue;
5607                }
5608
5609                // If no package is specified, we call all processes under the
5610                // give user id.
5611                if (packageName == null) {
5612                    if (app.userId != userId) {
5613                        continue;
5614                    }
5615                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5616                        continue;
5617                    }
5618                // Package has been specified, we want to hit all processes
5619                // that match it.  We need to qualify this by the processes
5620                // that are running under the specified app and user ID.
5621                } else {
5622                    final boolean isDep = app.pkgDeps != null
5623                            && app.pkgDeps.contains(packageName);
5624                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5625                        continue;
5626                    }
5627                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5628                        continue;
5629                    }
5630                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5631                        continue;
5632                    }
5633                }
5634
5635                // Process has passed all conditions, kill it!
5636                if (!doit) {
5637                    return true;
5638                }
5639                app.removed = true;
5640                procs.add(app);
5641            }
5642        }
5643
5644        int N = procs.size();
5645        for (int i=0; i<N; i++) {
5646            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5647        }
5648        updateOomAdjLocked();
5649        return N > 0;
5650    }
5651
5652    private final boolean forceStopPackageLocked(String name, int appId,
5653            boolean callerWillRestart, boolean purgeCache, boolean doit,
5654            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5655        int i;
5656        int N;
5657
5658        if (userId == UserHandle.USER_ALL && name == null) {
5659            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5660        }
5661
5662        if (appId < 0 && name != null) {
5663            try {
5664                appId = UserHandle.getAppId(
5665                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5666            } catch (RemoteException e) {
5667            }
5668        }
5669
5670        if (doit) {
5671            if (name != null) {
5672                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5673                        + " user=" + userId + ": " + reason);
5674            } else {
5675                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5676            }
5677
5678            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5679            for (int ip=pmap.size()-1; ip>=0; ip--) {
5680                SparseArray<Long> ba = pmap.valueAt(ip);
5681                for (i=ba.size()-1; i>=0; i--) {
5682                    boolean remove = false;
5683                    final int entUid = ba.keyAt(i);
5684                    if (name != null) {
5685                        if (userId == UserHandle.USER_ALL) {
5686                            if (UserHandle.getAppId(entUid) == appId) {
5687                                remove = true;
5688                            }
5689                        } else {
5690                            if (entUid == UserHandle.getUid(userId, appId)) {
5691                                remove = true;
5692                            }
5693                        }
5694                    } else if (UserHandle.getUserId(entUid) == userId) {
5695                        remove = true;
5696                    }
5697                    if (remove) {
5698                        ba.removeAt(i);
5699                    }
5700                }
5701                if (ba.size() == 0) {
5702                    pmap.removeAt(ip);
5703                }
5704            }
5705        }
5706
5707        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5708                -100, callerWillRestart, true, doit, evenPersistent,
5709                name == null ? ("stop user " + userId) : ("stop " + name));
5710
5711        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5712            if (!doit) {
5713                return true;
5714            }
5715            didSomething = true;
5716        }
5717
5718        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5719            if (!doit) {
5720                return true;
5721            }
5722            didSomething = true;
5723        }
5724
5725        if (name == null) {
5726            // Remove all sticky broadcasts from this user.
5727            mStickyBroadcasts.remove(userId);
5728        }
5729
5730        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5731        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5732                userId, providers)) {
5733            if (!doit) {
5734                return true;
5735            }
5736            didSomething = true;
5737        }
5738        N = providers.size();
5739        for (i=0; i<N; i++) {
5740            removeDyingProviderLocked(null, providers.get(i), true);
5741        }
5742
5743        // Remove transient permissions granted from/to this package/user
5744        removeUriPermissionsForPackageLocked(name, userId, false);
5745
5746        if (name == null || uninstalling) {
5747            // Remove pending intents.  For now we only do this when force
5748            // stopping users, because we have some problems when doing this
5749            // for packages -- app widgets are not currently cleaned up for
5750            // such packages, so they can be left with bad pending intents.
5751            if (mIntentSenderRecords.size() > 0) {
5752                Iterator<WeakReference<PendingIntentRecord>> it
5753                        = mIntentSenderRecords.values().iterator();
5754                while (it.hasNext()) {
5755                    WeakReference<PendingIntentRecord> wpir = it.next();
5756                    if (wpir == null) {
5757                        it.remove();
5758                        continue;
5759                    }
5760                    PendingIntentRecord pir = wpir.get();
5761                    if (pir == null) {
5762                        it.remove();
5763                        continue;
5764                    }
5765                    if (name == null) {
5766                        // Stopping user, remove all objects for the user.
5767                        if (pir.key.userId != userId) {
5768                            // Not the same user, skip it.
5769                            continue;
5770                        }
5771                    } else {
5772                        if (UserHandle.getAppId(pir.uid) != appId) {
5773                            // Different app id, skip it.
5774                            continue;
5775                        }
5776                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5777                            // Different user, skip it.
5778                            continue;
5779                        }
5780                        if (!pir.key.packageName.equals(name)) {
5781                            // Different package, skip it.
5782                            continue;
5783                        }
5784                    }
5785                    if (!doit) {
5786                        return true;
5787                    }
5788                    didSomething = true;
5789                    it.remove();
5790                    pir.canceled = true;
5791                    if (pir.key.activity != null) {
5792                        pir.key.activity.pendingResults.remove(pir.ref);
5793                    }
5794                }
5795            }
5796        }
5797
5798        if (doit) {
5799            if (purgeCache && name != null) {
5800                AttributeCache ac = AttributeCache.instance();
5801                if (ac != null) {
5802                    ac.removePackage(name);
5803                }
5804            }
5805            if (mBooted) {
5806                mStackSupervisor.resumeTopActivitiesLocked();
5807                mStackSupervisor.scheduleIdleLocked();
5808            }
5809        }
5810
5811        return didSomething;
5812    }
5813
5814    private final boolean removeProcessLocked(ProcessRecord app,
5815            boolean callerWillRestart, boolean allowRestart, String reason) {
5816        final String name = app.processName;
5817        final int uid = app.uid;
5818        if (DEBUG_PROCESSES) Slog.d(
5819            TAG, "Force removing proc " + app.toShortString() + " (" + name
5820            + "/" + uid + ")");
5821
5822        mProcessNames.remove(name, uid);
5823        mIsolatedProcesses.remove(app.uid);
5824        if (mHeavyWeightProcess == app) {
5825            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5826                    mHeavyWeightProcess.userId, 0));
5827            mHeavyWeightProcess = null;
5828        }
5829        boolean needRestart = false;
5830        if (app.pid > 0 && app.pid != MY_PID) {
5831            int pid = app.pid;
5832            synchronized (mPidsSelfLocked) {
5833                mPidsSelfLocked.remove(pid);
5834                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5835            }
5836            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5837            if (app.isolated) {
5838                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5839            }
5840            app.kill(reason, true);
5841            handleAppDiedLocked(app, true, allowRestart);
5842            removeLruProcessLocked(app);
5843
5844            if (app.persistent && !app.isolated) {
5845                if (!callerWillRestart) {
5846                    addAppLocked(app.info, false, null /* ABI override */);
5847                } else {
5848                    needRestart = true;
5849                }
5850            }
5851        } else {
5852            mRemovedProcesses.add(app);
5853        }
5854
5855        return needRestart;
5856    }
5857
5858    private final void processStartTimedOutLocked(ProcessRecord app) {
5859        final int pid = app.pid;
5860        boolean gone = false;
5861        synchronized (mPidsSelfLocked) {
5862            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5863            if (knownApp != null && knownApp.thread == null) {
5864                mPidsSelfLocked.remove(pid);
5865                gone = true;
5866            }
5867        }
5868
5869        if (gone) {
5870            Slog.w(TAG, "Process " + app + " failed to attach");
5871            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5872                    pid, app.uid, app.processName);
5873            mProcessNames.remove(app.processName, app.uid);
5874            mIsolatedProcesses.remove(app.uid);
5875            if (mHeavyWeightProcess == app) {
5876                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5877                        mHeavyWeightProcess.userId, 0));
5878                mHeavyWeightProcess = null;
5879            }
5880            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5881            if (app.isolated) {
5882                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5883            }
5884            // Take care of any launching providers waiting for this process.
5885            checkAppInLaunchingProvidersLocked(app, true);
5886            // Take care of any services that are waiting for the process.
5887            mServices.processStartTimedOutLocked(app);
5888            app.kill("start timeout", true);
5889            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5890                Slog.w(TAG, "Unattached app died before backup, skipping");
5891                try {
5892                    IBackupManager bm = IBackupManager.Stub.asInterface(
5893                            ServiceManager.getService(Context.BACKUP_SERVICE));
5894                    bm.agentDisconnected(app.info.packageName);
5895                } catch (RemoteException e) {
5896                    // Can't happen; the backup manager is local
5897                }
5898            }
5899            if (isPendingBroadcastProcessLocked(pid)) {
5900                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5901                skipPendingBroadcastLocked(pid);
5902            }
5903        } else {
5904            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5905        }
5906    }
5907
5908    private final boolean attachApplicationLocked(IApplicationThread thread,
5909            int pid) {
5910
5911        // Find the application record that is being attached...  either via
5912        // the pid if we are running in multiple processes, or just pull the
5913        // next app record if we are emulating process with anonymous threads.
5914        ProcessRecord app;
5915        if (pid != MY_PID && pid >= 0) {
5916            synchronized (mPidsSelfLocked) {
5917                app = mPidsSelfLocked.get(pid);
5918            }
5919        } else {
5920            app = null;
5921        }
5922
5923        if (app == null) {
5924            Slog.w(TAG, "No pending application record for pid " + pid
5925                    + " (IApplicationThread " + thread + "); dropping process");
5926            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5927            if (pid > 0 && pid != MY_PID) {
5928                Process.killProcessQuiet(pid);
5929                //TODO: Process.killProcessGroup(app.info.uid, pid);
5930            } else {
5931                try {
5932                    thread.scheduleExit();
5933                } catch (Exception e) {
5934                    // Ignore exceptions.
5935                }
5936            }
5937            return false;
5938        }
5939
5940        // If this application record is still attached to a previous
5941        // process, clean it up now.
5942        if (app.thread != null) {
5943            handleAppDiedLocked(app, true, true);
5944        }
5945
5946        // Tell the process all about itself.
5947
5948        if (localLOGV) Slog.v(
5949                TAG, "Binding process pid " + pid + " to record " + app);
5950
5951        final String processName = app.processName;
5952        try {
5953            AppDeathRecipient adr = new AppDeathRecipient(
5954                    app, pid, thread);
5955            thread.asBinder().linkToDeath(adr, 0);
5956            app.deathRecipient = adr;
5957        } catch (RemoteException e) {
5958            app.resetPackageList(mProcessStats);
5959            startProcessLocked(app, "link fail", processName);
5960            return false;
5961        }
5962
5963        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5964
5965        app.makeActive(thread, mProcessStats);
5966        app.curAdj = app.setAdj = -100;
5967        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5968        app.forcingToForeground = null;
5969        updateProcessForegroundLocked(app, false, false);
5970        app.hasShownUi = false;
5971        app.debugging = false;
5972        app.cached = false;
5973
5974        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5975
5976        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5977        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5978
5979        if (!normalMode) {
5980            Slog.i(TAG, "Launching preboot mode app: " + app);
5981        }
5982
5983        if (localLOGV) Slog.v(
5984            TAG, "New app record " + app
5985            + " thread=" + thread.asBinder() + " pid=" + pid);
5986        try {
5987            int testMode = IApplicationThread.DEBUG_OFF;
5988            if (mDebugApp != null && mDebugApp.equals(processName)) {
5989                testMode = mWaitForDebugger
5990                    ? IApplicationThread.DEBUG_WAIT
5991                    : IApplicationThread.DEBUG_ON;
5992                app.debugging = true;
5993                if (mDebugTransient) {
5994                    mDebugApp = mOrigDebugApp;
5995                    mWaitForDebugger = mOrigWaitForDebugger;
5996                }
5997            }
5998            String profileFile = app.instrumentationProfileFile;
5999            ParcelFileDescriptor profileFd = null;
6000            int samplingInterval = 0;
6001            boolean profileAutoStop = false;
6002            if (mProfileApp != null && mProfileApp.equals(processName)) {
6003                mProfileProc = app;
6004                profileFile = mProfileFile;
6005                profileFd = mProfileFd;
6006                samplingInterval = mSamplingInterval;
6007                profileAutoStop = mAutoStopProfiler;
6008            }
6009            boolean enableOpenGlTrace = false;
6010            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6011                enableOpenGlTrace = true;
6012                mOpenGlTraceApp = null;
6013            }
6014
6015            // If the app is being launched for restore or full backup, set it up specially
6016            boolean isRestrictedBackupMode = false;
6017            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6018                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6019                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6020                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6021            }
6022
6023            ensurePackageDexOpt(app.instrumentationInfo != null
6024                    ? app.instrumentationInfo.packageName
6025                    : app.info.packageName);
6026            if (app.instrumentationClass != null) {
6027                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6028            }
6029            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6030                    + processName + " with config " + mConfiguration);
6031            ApplicationInfo appInfo = app.instrumentationInfo != null
6032                    ? app.instrumentationInfo : app.info;
6033            app.compat = compatibilityInfoForPackageLocked(appInfo);
6034            if (profileFd != null) {
6035                profileFd = profileFd.dup();
6036            }
6037            ProfilerInfo profilerInfo = profileFile == null ? null
6038                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6039            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6040                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6041                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6042                    isRestrictedBackupMode || !normalMode, app.persistent,
6043                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6044                    mCoreSettingsObserver.getCoreSettingsLocked());
6045            updateLruProcessLocked(app, false, null);
6046            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6047        } catch (Exception e) {
6048            // todo: Yikes!  What should we do?  For now we will try to
6049            // start another process, but that could easily get us in
6050            // an infinite loop of restarting processes...
6051            Slog.w(TAG, "Exception thrown during bind!", e);
6052
6053            app.resetPackageList(mProcessStats);
6054            app.unlinkDeathRecipient();
6055            startProcessLocked(app, "bind fail", processName);
6056            return false;
6057        }
6058
6059        // Remove this record from the list of starting applications.
6060        mPersistentStartingProcesses.remove(app);
6061        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6062                "Attach application locked removing on hold: " + app);
6063        mProcessesOnHold.remove(app);
6064
6065        boolean badApp = false;
6066        boolean didSomething = false;
6067
6068        // See if the top visible activity is waiting to run in this process...
6069        if (normalMode) {
6070            try {
6071                if (mStackSupervisor.attachApplicationLocked(app)) {
6072                    didSomething = true;
6073                }
6074            } catch (Exception e) {
6075                badApp = true;
6076            }
6077        }
6078
6079        // Find any services that should be running in this process...
6080        if (!badApp) {
6081            try {
6082                didSomething |= mServices.attachApplicationLocked(app, processName);
6083            } catch (Exception e) {
6084                badApp = true;
6085            }
6086        }
6087
6088        // Check if a next-broadcast receiver is in this process...
6089        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6090            try {
6091                didSomething |= sendPendingBroadcastsLocked(app);
6092            } catch (Exception e) {
6093                // If the app died trying to launch the receiver we declare it 'bad'
6094                badApp = true;
6095            }
6096        }
6097
6098        // Check whether the next backup agent is in this process...
6099        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6100            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6101            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6102            try {
6103                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6104                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6105                        mBackupTarget.backupMode);
6106            } catch (Exception e) {
6107                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6108                e.printStackTrace();
6109            }
6110        }
6111
6112        if (badApp) {
6113            // todo: Also need to kill application to deal with all
6114            // kinds of exceptions.
6115            handleAppDiedLocked(app, false, true);
6116            return false;
6117        }
6118
6119        if (!didSomething) {
6120            updateOomAdjLocked();
6121        }
6122
6123        return true;
6124    }
6125
6126    @Override
6127    public final void attachApplication(IApplicationThread thread) {
6128        synchronized (this) {
6129            int callingPid = Binder.getCallingPid();
6130            final long origId = Binder.clearCallingIdentity();
6131            attachApplicationLocked(thread, callingPid);
6132            Binder.restoreCallingIdentity(origId);
6133        }
6134    }
6135
6136    @Override
6137    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6138        final long origId = Binder.clearCallingIdentity();
6139        synchronized (this) {
6140            ActivityStack stack = ActivityRecord.getStackLocked(token);
6141            if (stack != null) {
6142                ActivityRecord r =
6143                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6144                if (stopProfiling) {
6145                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6146                        try {
6147                            mProfileFd.close();
6148                        } catch (IOException e) {
6149                        }
6150                        clearProfilerLocked();
6151                    }
6152                }
6153            }
6154        }
6155        Binder.restoreCallingIdentity(origId);
6156    }
6157
6158    void postEnableScreenAfterBootLocked() {
6159        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6160    }
6161
6162    void enableScreenAfterBoot() {
6163        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6164                SystemClock.uptimeMillis());
6165        mWindowManager.enableScreenAfterBoot();
6166
6167        synchronized (this) {
6168            updateEventDispatchingLocked();
6169        }
6170    }
6171
6172    @Override
6173    public void showBootMessage(final CharSequence msg, final boolean always) {
6174        enforceNotIsolatedCaller("showBootMessage");
6175        mWindowManager.showBootMessage(msg, always);
6176    }
6177
6178    @Override
6179    public void keyguardWaitingForActivityDrawn() {
6180        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6181        final long token = Binder.clearCallingIdentity();
6182        try {
6183            synchronized (this) {
6184                if (DEBUG_LOCKSCREEN) logLockScreen("");
6185                mWindowManager.keyguardWaitingForActivityDrawn();
6186            }
6187        } finally {
6188            Binder.restoreCallingIdentity(token);
6189        }
6190    }
6191
6192    final void finishBooting() {
6193        // Register receivers to handle package update events
6194        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6195
6196        // Let system services know.
6197        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6198
6199        synchronized (this) {
6200            // Ensure that any processes we had put on hold are now started
6201            // up.
6202            final int NP = mProcessesOnHold.size();
6203            if (NP > 0) {
6204                ArrayList<ProcessRecord> procs =
6205                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6206                for (int ip=0; ip<NP; ip++) {
6207                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6208                            + procs.get(ip));
6209                    startProcessLocked(procs.get(ip), "on-hold", null);
6210                }
6211            }
6212
6213            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6214                // Start looking for apps that are abusing wake locks.
6215                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6216                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6217                // Tell anyone interested that we are done booting!
6218                SystemProperties.set("sys.boot_completed", "1");
6219                SystemProperties.set("dev.bootcomplete", "1");
6220                for (int i=0; i<mStartedUsers.size(); i++) {
6221                    UserStartedState uss = mStartedUsers.valueAt(i);
6222                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6223                        uss.mState = UserStartedState.STATE_RUNNING;
6224                        final int userId = mStartedUsers.keyAt(i);
6225                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6226                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6227                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6228                        broadcastIntentLocked(null, null, intent, null,
6229                                new IIntentReceiver.Stub() {
6230                                    @Override
6231                                    public void performReceive(Intent intent, int resultCode,
6232                                            String data, Bundle extras, boolean ordered,
6233                                            boolean sticky, int sendingUser) {
6234                                        synchronized (ActivityManagerService.this) {
6235                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6236                                                    true, false);
6237                                        }
6238                                    }
6239                                },
6240                                0, null, null,
6241                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6242                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6243                                userId);
6244                    }
6245                }
6246                scheduleStartProfilesLocked();
6247            }
6248        }
6249    }
6250
6251    final void ensureBootCompleted() {
6252        boolean booting;
6253        boolean enableScreen;
6254        synchronized (this) {
6255            booting = mBooting;
6256            mBooting = false;
6257            enableScreen = !mBooted;
6258            mBooted = true;
6259        }
6260
6261        if (booting) {
6262            finishBooting();
6263        }
6264
6265        if (enableScreen) {
6266            enableScreenAfterBoot();
6267        }
6268    }
6269
6270    @Override
6271    public final void activityResumed(IBinder token) {
6272        final long origId = Binder.clearCallingIdentity();
6273        synchronized(this) {
6274            ActivityStack stack = ActivityRecord.getStackLocked(token);
6275            if (stack != null) {
6276                ActivityRecord.activityResumedLocked(token);
6277            }
6278        }
6279        Binder.restoreCallingIdentity(origId);
6280    }
6281
6282    @Override
6283    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6284        final long origId = Binder.clearCallingIdentity();
6285        synchronized(this) {
6286            ActivityStack stack = ActivityRecord.getStackLocked(token);
6287            if (stack != null) {
6288                stack.activityPausedLocked(token, false, persistentState);
6289            }
6290        }
6291        Binder.restoreCallingIdentity(origId);
6292    }
6293
6294    @Override
6295    public final void activityStopped(IBinder token, Bundle icicle,
6296            PersistableBundle persistentState, CharSequence description) {
6297        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6298
6299        // Refuse possible leaked file descriptors
6300        if (icicle != null && icicle.hasFileDescriptors()) {
6301            throw new IllegalArgumentException("File descriptors passed in Bundle");
6302        }
6303
6304        final long origId = Binder.clearCallingIdentity();
6305
6306        synchronized (this) {
6307            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6308            if (r != null) {
6309                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6310            }
6311        }
6312
6313        trimApplications();
6314
6315        Binder.restoreCallingIdentity(origId);
6316    }
6317
6318    @Override
6319    public final void activityDestroyed(IBinder token) {
6320        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6321        synchronized (this) {
6322            ActivityStack stack = ActivityRecord.getStackLocked(token);
6323            if (stack != null) {
6324                stack.activityDestroyedLocked(token);
6325            }
6326        }
6327    }
6328
6329    @Override
6330    public final void backgroundResourcesReleased(IBinder token) {
6331        final long origId = Binder.clearCallingIdentity();
6332        try {
6333            synchronized (this) {
6334                ActivityStack stack = ActivityRecord.getStackLocked(token);
6335                if (stack != null) {
6336                    stack.backgroundResourcesReleased(token);
6337                }
6338            }
6339        } finally {
6340            Binder.restoreCallingIdentity(origId);
6341        }
6342    }
6343
6344    @Override
6345    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6346        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6347    }
6348
6349    @Override
6350    public final void notifyEnterAnimationComplete(IBinder token) {
6351        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6352    }
6353
6354    @Override
6355    public String getCallingPackage(IBinder token) {
6356        synchronized (this) {
6357            ActivityRecord r = getCallingRecordLocked(token);
6358            return r != null ? r.info.packageName : null;
6359        }
6360    }
6361
6362    @Override
6363    public ComponentName getCallingActivity(IBinder token) {
6364        synchronized (this) {
6365            ActivityRecord r = getCallingRecordLocked(token);
6366            return r != null ? r.intent.getComponent() : null;
6367        }
6368    }
6369
6370    private ActivityRecord getCallingRecordLocked(IBinder token) {
6371        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6372        if (r == null) {
6373            return null;
6374        }
6375        return r.resultTo;
6376    }
6377
6378    @Override
6379    public ComponentName getActivityClassForToken(IBinder token) {
6380        synchronized(this) {
6381            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6382            if (r == null) {
6383                return null;
6384            }
6385            return r.intent.getComponent();
6386        }
6387    }
6388
6389    @Override
6390    public String getPackageForToken(IBinder token) {
6391        synchronized(this) {
6392            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6393            if (r == null) {
6394                return null;
6395            }
6396            return r.packageName;
6397        }
6398    }
6399
6400    @Override
6401    public IIntentSender getIntentSender(int type,
6402            String packageName, IBinder token, String resultWho,
6403            int requestCode, Intent[] intents, String[] resolvedTypes,
6404            int flags, Bundle options, int userId) {
6405        enforceNotIsolatedCaller("getIntentSender");
6406        // Refuse possible leaked file descriptors
6407        if (intents != null) {
6408            if (intents.length < 1) {
6409                throw new IllegalArgumentException("Intents array length must be >= 1");
6410            }
6411            for (int i=0; i<intents.length; i++) {
6412                Intent intent = intents[i];
6413                if (intent != null) {
6414                    if (intent.hasFileDescriptors()) {
6415                        throw new IllegalArgumentException("File descriptors passed in Intent");
6416                    }
6417                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6418                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6419                        throw new IllegalArgumentException(
6420                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6421                    }
6422                    intents[i] = new Intent(intent);
6423                }
6424            }
6425            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6426                throw new IllegalArgumentException(
6427                        "Intent array length does not match resolvedTypes length");
6428            }
6429        }
6430        if (options != null) {
6431            if (options.hasFileDescriptors()) {
6432                throw new IllegalArgumentException("File descriptors passed in options");
6433            }
6434        }
6435
6436        synchronized(this) {
6437            int callingUid = Binder.getCallingUid();
6438            int origUserId = userId;
6439            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6440                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6441                    ALLOW_NON_FULL, "getIntentSender", null);
6442            if (origUserId == UserHandle.USER_CURRENT) {
6443                // We don't want to evaluate this until the pending intent is
6444                // actually executed.  However, we do want to always do the
6445                // security checking for it above.
6446                userId = UserHandle.USER_CURRENT;
6447            }
6448            try {
6449                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6450                    int uid = AppGlobals.getPackageManager()
6451                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6452                    if (!UserHandle.isSameApp(callingUid, uid)) {
6453                        String msg = "Permission Denial: getIntentSender() from pid="
6454                            + Binder.getCallingPid()
6455                            + ", uid=" + Binder.getCallingUid()
6456                            + ", (need uid=" + uid + ")"
6457                            + " is not allowed to send as package " + packageName;
6458                        Slog.w(TAG, msg);
6459                        throw new SecurityException(msg);
6460                    }
6461                }
6462
6463                return getIntentSenderLocked(type, packageName, callingUid, userId,
6464                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6465
6466            } catch (RemoteException e) {
6467                throw new SecurityException(e);
6468            }
6469        }
6470    }
6471
6472    IIntentSender getIntentSenderLocked(int type, String packageName,
6473            int callingUid, int userId, IBinder token, String resultWho,
6474            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6475            Bundle options) {
6476        if (DEBUG_MU)
6477            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6478        ActivityRecord activity = null;
6479        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6480            activity = ActivityRecord.isInStackLocked(token);
6481            if (activity == null) {
6482                return null;
6483            }
6484            if (activity.finishing) {
6485                return null;
6486            }
6487        }
6488
6489        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6490        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6491        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6492        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6493                |PendingIntent.FLAG_UPDATE_CURRENT);
6494
6495        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6496                type, packageName, activity, resultWho,
6497                requestCode, intents, resolvedTypes, flags, options, userId);
6498        WeakReference<PendingIntentRecord> ref;
6499        ref = mIntentSenderRecords.get(key);
6500        PendingIntentRecord rec = ref != null ? ref.get() : null;
6501        if (rec != null) {
6502            if (!cancelCurrent) {
6503                if (updateCurrent) {
6504                    if (rec.key.requestIntent != null) {
6505                        rec.key.requestIntent.replaceExtras(intents != null ?
6506                                intents[intents.length - 1] : null);
6507                    }
6508                    if (intents != null) {
6509                        intents[intents.length-1] = rec.key.requestIntent;
6510                        rec.key.allIntents = intents;
6511                        rec.key.allResolvedTypes = resolvedTypes;
6512                    } else {
6513                        rec.key.allIntents = null;
6514                        rec.key.allResolvedTypes = null;
6515                    }
6516                }
6517                return rec;
6518            }
6519            rec.canceled = true;
6520            mIntentSenderRecords.remove(key);
6521        }
6522        if (noCreate) {
6523            return rec;
6524        }
6525        rec = new PendingIntentRecord(this, key, callingUid);
6526        mIntentSenderRecords.put(key, rec.ref);
6527        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6528            if (activity.pendingResults == null) {
6529                activity.pendingResults
6530                        = new HashSet<WeakReference<PendingIntentRecord>>();
6531            }
6532            activity.pendingResults.add(rec.ref);
6533        }
6534        return rec;
6535    }
6536
6537    @Override
6538    public void cancelIntentSender(IIntentSender sender) {
6539        if (!(sender instanceof PendingIntentRecord)) {
6540            return;
6541        }
6542        synchronized(this) {
6543            PendingIntentRecord rec = (PendingIntentRecord)sender;
6544            try {
6545                int uid = AppGlobals.getPackageManager()
6546                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6547                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6548                    String msg = "Permission Denial: cancelIntentSender() from pid="
6549                        + Binder.getCallingPid()
6550                        + ", uid=" + Binder.getCallingUid()
6551                        + " is not allowed to cancel packges "
6552                        + rec.key.packageName;
6553                    Slog.w(TAG, msg);
6554                    throw new SecurityException(msg);
6555                }
6556            } catch (RemoteException e) {
6557                throw new SecurityException(e);
6558            }
6559            cancelIntentSenderLocked(rec, true);
6560        }
6561    }
6562
6563    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6564        rec.canceled = true;
6565        mIntentSenderRecords.remove(rec.key);
6566        if (cleanActivity && rec.key.activity != null) {
6567            rec.key.activity.pendingResults.remove(rec.ref);
6568        }
6569    }
6570
6571    @Override
6572    public String getPackageForIntentSender(IIntentSender pendingResult) {
6573        if (!(pendingResult instanceof PendingIntentRecord)) {
6574            return null;
6575        }
6576        try {
6577            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6578            return res.key.packageName;
6579        } catch (ClassCastException e) {
6580        }
6581        return null;
6582    }
6583
6584    @Override
6585    public int getUidForIntentSender(IIntentSender sender) {
6586        if (sender instanceof PendingIntentRecord) {
6587            try {
6588                PendingIntentRecord res = (PendingIntentRecord)sender;
6589                return res.uid;
6590            } catch (ClassCastException e) {
6591            }
6592        }
6593        return -1;
6594    }
6595
6596    @Override
6597    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6598        if (!(pendingResult instanceof PendingIntentRecord)) {
6599            return false;
6600        }
6601        try {
6602            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6603            if (res.key.allIntents == null) {
6604                return false;
6605            }
6606            for (int i=0; i<res.key.allIntents.length; i++) {
6607                Intent intent = res.key.allIntents[i];
6608                if (intent.getPackage() != null && intent.getComponent() != null) {
6609                    return false;
6610                }
6611            }
6612            return true;
6613        } catch (ClassCastException e) {
6614        }
6615        return false;
6616    }
6617
6618    @Override
6619    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6620        if (!(pendingResult instanceof PendingIntentRecord)) {
6621            return false;
6622        }
6623        try {
6624            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6625            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6626                return true;
6627            }
6628            return false;
6629        } catch (ClassCastException e) {
6630        }
6631        return false;
6632    }
6633
6634    @Override
6635    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6636        if (!(pendingResult instanceof PendingIntentRecord)) {
6637            return null;
6638        }
6639        try {
6640            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6641            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6642        } catch (ClassCastException e) {
6643        }
6644        return null;
6645    }
6646
6647    @Override
6648    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6649        if (!(pendingResult instanceof PendingIntentRecord)) {
6650            return null;
6651        }
6652        try {
6653            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6654            Intent intent = res.key.requestIntent;
6655            if (intent != null) {
6656                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6657                        || res.lastTagPrefix.equals(prefix))) {
6658                    return res.lastTag;
6659                }
6660                res.lastTagPrefix = prefix;
6661                StringBuilder sb = new StringBuilder(128);
6662                if (prefix != null) {
6663                    sb.append(prefix);
6664                }
6665                if (intent.getAction() != null) {
6666                    sb.append(intent.getAction());
6667                } else if (intent.getComponent() != null) {
6668                    intent.getComponent().appendShortString(sb);
6669                } else {
6670                    sb.append("?");
6671                }
6672                return res.lastTag = sb.toString();
6673            }
6674        } catch (ClassCastException e) {
6675        }
6676        return null;
6677    }
6678
6679    @Override
6680    public void setProcessLimit(int max) {
6681        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6682                "setProcessLimit()");
6683        synchronized (this) {
6684            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6685            mProcessLimitOverride = max;
6686        }
6687        trimApplications();
6688    }
6689
6690    @Override
6691    public int getProcessLimit() {
6692        synchronized (this) {
6693            return mProcessLimitOverride;
6694        }
6695    }
6696
6697    void foregroundTokenDied(ForegroundToken token) {
6698        synchronized (ActivityManagerService.this) {
6699            synchronized (mPidsSelfLocked) {
6700                ForegroundToken cur
6701                    = mForegroundProcesses.get(token.pid);
6702                if (cur != token) {
6703                    return;
6704                }
6705                mForegroundProcesses.remove(token.pid);
6706                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6707                if (pr == null) {
6708                    return;
6709                }
6710                pr.forcingToForeground = null;
6711                updateProcessForegroundLocked(pr, false, false);
6712            }
6713            updateOomAdjLocked();
6714        }
6715    }
6716
6717    @Override
6718    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6719        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6720                "setProcessForeground()");
6721        synchronized(this) {
6722            boolean changed = false;
6723
6724            synchronized (mPidsSelfLocked) {
6725                ProcessRecord pr = mPidsSelfLocked.get(pid);
6726                if (pr == null && isForeground) {
6727                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6728                    return;
6729                }
6730                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6731                if (oldToken != null) {
6732                    oldToken.token.unlinkToDeath(oldToken, 0);
6733                    mForegroundProcesses.remove(pid);
6734                    if (pr != null) {
6735                        pr.forcingToForeground = null;
6736                    }
6737                    changed = true;
6738                }
6739                if (isForeground && token != null) {
6740                    ForegroundToken newToken = new ForegroundToken() {
6741                        @Override
6742                        public void binderDied() {
6743                            foregroundTokenDied(this);
6744                        }
6745                    };
6746                    newToken.pid = pid;
6747                    newToken.token = token;
6748                    try {
6749                        token.linkToDeath(newToken, 0);
6750                        mForegroundProcesses.put(pid, newToken);
6751                        pr.forcingToForeground = token;
6752                        changed = true;
6753                    } catch (RemoteException e) {
6754                        // If the process died while doing this, we will later
6755                        // do the cleanup with the process death link.
6756                    }
6757                }
6758            }
6759
6760            if (changed) {
6761                updateOomAdjLocked();
6762            }
6763        }
6764    }
6765
6766    // =========================================================
6767    // PERMISSIONS
6768    // =========================================================
6769
6770    static class PermissionController extends IPermissionController.Stub {
6771        ActivityManagerService mActivityManagerService;
6772        PermissionController(ActivityManagerService activityManagerService) {
6773            mActivityManagerService = activityManagerService;
6774        }
6775
6776        @Override
6777        public boolean checkPermission(String permission, int pid, int uid) {
6778            return mActivityManagerService.checkPermission(permission, pid,
6779                    uid) == PackageManager.PERMISSION_GRANTED;
6780        }
6781    }
6782
6783    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6784        @Override
6785        public int checkComponentPermission(String permission, int pid, int uid,
6786                int owningUid, boolean exported) {
6787            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6788                    owningUid, exported);
6789        }
6790
6791        @Override
6792        public Object getAMSLock() {
6793            return ActivityManagerService.this;
6794        }
6795    }
6796
6797    /**
6798     * This can be called with or without the global lock held.
6799     */
6800    int checkComponentPermission(String permission, int pid, int uid,
6801            int owningUid, boolean exported) {
6802        // We might be performing an operation on behalf of an indirect binder
6803        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6804        // client identity accordingly before proceeding.
6805        Identity tlsIdentity = sCallerIdentity.get();
6806        if (tlsIdentity != null) {
6807            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6808                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6809            uid = tlsIdentity.uid;
6810            pid = tlsIdentity.pid;
6811        }
6812
6813        if (pid == MY_PID) {
6814            return PackageManager.PERMISSION_GRANTED;
6815        }
6816
6817        return ActivityManager.checkComponentPermission(permission, uid,
6818                owningUid, exported);
6819    }
6820
6821    /**
6822     * As the only public entry point for permissions checking, this method
6823     * can enforce the semantic that requesting a check on a null global
6824     * permission is automatically denied.  (Internally a null permission
6825     * string is used when calling {@link #checkComponentPermission} in cases
6826     * when only uid-based security is needed.)
6827     *
6828     * This can be called with or without the global lock held.
6829     */
6830    @Override
6831    public int checkPermission(String permission, int pid, int uid) {
6832        if (permission == null) {
6833            return PackageManager.PERMISSION_DENIED;
6834        }
6835        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6836    }
6837
6838    /**
6839     * Binder IPC calls go through the public entry point.
6840     * This can be called with or without the global lock held.
6841     */
6842    int checkCallingPermission(String permission) {
6843        return checkPermission(permission,
6844                Binder.getCallingPid(),
6845                UserHandle.getAppId(Binder.getCallingUid()));
6846    }
6847
6848    /**
6849     * This can be called with or without the global lock held.
6850     */
6851    void enforceCallingPermission(String permission, String func) {
6852        if (checkCallingPermission(permission)
6853                == PackageManager.PERMISSION_GRANTED) {
6854            return;
6855        }
6856
6857        String msg = "Permission Denial: " + func + " from pid="
6858                + Binder.getCallingPid()
6859                + ", uid=" + Binder.getCallingUid()
6860                + " requires " + permission;
6861        Slog.w(TAG, msg);
6862        throw new SecurityException(msg);
6863    }
6864
6865    /**
6866     * Determine if UID is holding permissions required to access {@link Uri} in
6867     * the given {@link ProviderInfo}. Final permission checking is always done
6868     * in {@link ContentProvider}.
6869     */
6870    private final boolean checkHoldingPermissionsLocked(
6871            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6872        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6873                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6874        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6875            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6876                    != PERMISSION_GRANTED) {
6877                return false;
6878            }
6879        }
6880        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6881    }
6882
6883    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6884            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6885        if (pi.applicationInfo.uid == uid) {
6886            return true;
6887        } else if (!pi.exported) {
6888            return false;
6889        }
6890
6891        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6892        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6893        try {
6894            // check if target holds top-level <provider> permissions
6895            if (!readMet && pi.readPermission != null && considerUidPermissions
6896                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6897                readMet = true;
6898            }
6899            if (!writeMet && pi.writePermission != null && considerUidPermissions
6900                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6901                writeMet = true;
6902            }
6903
6904            // track if unprotected read/write is allowed; any denied
6905            // <path-permission> below removes this ability
6906            boolean allowDefaultRead = pi.readPermission == null;
6907            boolean allowDefaultWrite = pi.writePermission == null;
6908
6909            // check if target holds any <path-permission> that match uri
6910            final PathPermission[] pps = pi.pathPermissions;
6911            if (pps != null) {
6912                final String path = grantUri.uri.getPath();
6913                int i = pps.length;
6914                while (i > 0 && (!readMet || !writeMet)) {
6915                    i--;
6916                    PathPermission pp = pps[i];
6917                    if (pp.match(path)) {
6918                        if (!readMet) {
6919                            final String pprperm = pp.getReadPermission();
6920                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6921                                    + pprperm + " for " + pp.getPath()
6922                                    + ": match=" + pp.match(path)
6923                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6924                            if (pprperm != null) {
6925                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6926                                        == PERMISSION_GRANTED) {
6927                                    readMet = true;
6928                                } else {
6929                                    allowDefaultRead = false;
6930                                }
6931                            }
6932                        }
6933                        if (!writeMet) {
6934                            final String ppwperm = pp.getWritePermission();
6935                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6936                                    + ppwperm + " for " + pp.getPath()
6937                                    + ": match=" + pp.match(path)
6938                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6939                            if (ppwperm != null) {
6940                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6941                                        == PERMISSION_GRANTED) {
6942                                    writeMet = true;
6943                                } else {
6944                                    allowDefaultWrite = false;
6945                                }
6946                            }
6947                        }
6948                    }
6949                }
6950            }
6951
6952            // grant unprotected <provider> read/write, if not blocked by
6953            // <path-permission> above
6954            if (allowDefaultRead) readMet = true;
6955            if (allowDefaultWrite) writeMet = true;
6956
6957        } catch (RemoteException e) {
6958            return false;
6959        }
6960
6961        return readMet && writeMet;
6962    }
6963
6964    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6965        ProviderInfo pi = null;
6966        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6967        if (cpr != null) {
6968            pi = cpr.info;
6969        } else {
6970            try {
6971                pi = AppGlobals.getPackageManager().resolveContentProvider(
6972                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6973            } catch (RemoteException ex) {
6974            }
6975        }
6976        return pi;
6977    }
6978
6979    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6980        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6981        if (targetUris != null) {
6982            return targetUris.get(grantUri);
6983        }
6984        return null;
6985    }
6986
6987    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6988            String targetPkg, int targetUid, GrantUri grantUri) {
6989        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6990        if (targetUris == null) {
6991            targetUris = Maps.newArrayMap();
6992            mGrantedUriPermissions.put(targetUid, targetUris);
6993        }
6994
6995        UriPermission perm = targetUris.get(grantUri);
6996        if (perm == null) {
6997            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6998            targetUris.put(grantUri, perm);
6999        }
7000
7001        return perm;
7002    }
7003
7004    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7005            final int modeFlags) {
7006        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7007        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7008                : UriPermission.STRENGTH_OWNED;
7009
7010        // Root gets to do everything.
7011        if (uid == 0) {
7012            return true;
7013        }
7014
7015        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7016        if (perms == null) return false;
7017
7018        // First look for exact match
7019        final UriPermission exactPerm = perms.get(grantUri);
7020        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7021            return true;
7022        }
7023
7024        // No exact match, look for prefixes
7025        final int N = perms.size();
7026        for (int i = 0; i < N; i++) {
7027            final UriPermission perm = perms.valueAt(i);
7028            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7029                    && perm.getStrength(modeFlags) >= minStrength) {
7030                return true;
7031            }
7032        }
7033
7034        return false;
7035    }
7036
7037    /**
7038     * @param uri This uri must NOT contain an embedded userId.
7039     * @param userId The userId in which the uri is to be resolved.
7040     */
7041    @Override
7042    public int checkUriPermission(Uri uri, int pid, int uid,
7043            final int modeFlags, int userId) {
7044        enforceNotIsolatedCaller("checkUriPermission");
7045
7046        // Another redirected-binder-call permissions check as in
7047        // {@link checkComponentPermission}.
7048        Identity tlsIdentity = sCallerIdentity.get();
7049        if (tlsIdentity != null) {
7050            uid = tlsIdentity.uid;
7051            pid = tlsIdentity.pid;
7052        }
7053
7054        // Our own process gets to do everything.
7055        if (pid == MY_PID) {
7056            return PackageManager.PERMISSION_GRANTED;
7057        }
7058        synchronized (this) {
7059            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7060                    ? PackageManager.PERMISSION_GRANTED
7061                    : PackageManager.PERMISSION_DENIED;
7062        }
7063    }
7064
7065    /**
7066     * Check if the targetPkg can be granted permission to access uri by
7067     * the callingUid using the given modeFlags.  Throws a security exception
7068     * if callingUid is not allowed to do this.  Returns the uid of the target
7069     * if the URI permission grant should be performed; returns -1 if it is not
7070     * needed (for example targetPkg already has permission to access the URI).
7071     * If you already know the uid of the target, you can supply it in
7072     * lastTargetUid else set that to -1.
7073     */
7074    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7075            final int modeFlags, int lastTargetUid) {
7076        if (!Intent.isAccessUriMode(modeFlags)) {
7077            return -1;
7078        }
7079
7080        if (targetPkg != null) {
7081            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7082                    "Checking grant " + targetPkg + " permission to " + grantUri);
7083        }
7084
7085        final IPackageManager pm = AppGlobals.getPackageManager();
7086
7087        // If this is not a content: uri, we can't do anything with it.
7088        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7089            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7090                    "Can't grant URI permission for non-content URI: " + grantUri);
7091            return -1;
7092        }
7093
7094        final String authority = grantUri.uri.getAuthority();
7095        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7096        if (pi == null) {
7097            Slog.w(TAG, "No content provider found for permission check: " +
7098                    grantUri.uri.toSafeString());
7099            return -1;
7100        }
7101
7102        int targetUid = lastTargetUid;
7103        if (targetUid < 0 && targetPkg != null) {
7104            try {
7105                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7106                if (targetUid < 0) {
7107                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7108                            "Can't grant URI permission no uid for: " + targetPkg);
7109                    return -1;
7110                }
7111            } catch (RemoteException ex) {
7112                return -1;
7113            }
7114        }
7115
7116        if (targetUid >= 0) {
7117            // First...  does the target actually need this permission?
7118            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7119                // No need to grant the target this permission.
7120                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7121                        "Target " + targetPkg + " already has full permission to " + grantUri);
7122                return -1;
7123            }
7124        } else {
7125            // First...  there is no target package, so can anyone access it?
7126            boolean allowed = pi.exported;
7127            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7128                if (pi.readPermission != null) {
7129                    allowed = false;
7130                }
7131            }
7132            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7133                if (pi.writePermission != null) {
7134                    allowed = false;
7135                }
7136            }
7137            if (allowed) {
7138                return -1;
7139            }
7140        }
7141
7142        /* There is a special cross user grant if:
7143         * - The target is on another user.
7144         * - Apps on the current user can access the uri without any uid permissions.
7145         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7146         * grant uri permissions.
7147         */
7148        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7149                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7150                modeFlags, false /*without considering the uid permissions*/);
7151
7152        // Second...  is the provider allowing granting of URI permissions?
7153        if (!specialCrossUserGrant) {
7154            if (!pi.grantUriPermissions) {
7155                throw new SecurityException("Provider " + pi.packageName
7156                        + "/" + pi.name
7157                        + " does not allow granting of Uri permissions (uri "
7158                        + grantUri + ")");
7159            }
7160            if (pi.uriPermissionPatterns != null) {
7161                final int N = pi.uriPermissionPatterns.length;
7162                boolean allowed = false;
7163                for (int i=0; i<N; i++) {
7164                    if (pi.uriPermissionPatterns[i] != null
7165                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7166                        allowed = true;
7167                        break;
7168                    }
7169                }
7170                if (!allowed) {
7171                    throw new SecurityException("Provider " + pi.packageName
7172                            + "/" + pi.name
7173                            + " does not allow granting of permission to path of Uri "
7174                            + grantUri);
7175                }
7176            }
7177        }
7178
7179        // Third...  does the caller itself have permission to access
7180        // this uri?
7181        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7182            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7183                // Require they hold a strong enough Uri permission
7184                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7185                    throw new SecurityException("Uid " + callingUid
7186                            + " does not have permission to uri " + grantUri);
7187                }
7188            }
7189        }
7190        return targetUid;
7191    }
7192
7193    /**
7194     * @param uri This uri must NOT contain an embedded userId.
7195     * @param userId The userId in which the uri is to be resolved.
7196     */
7197    @Override
7198    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7199            final int modeFlags, int userId) {
7200        enforceNotIsolatedCaller("checkGrantUriPermission");
7201        synchronized(this) {
7202            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7203                    new GrantUri(userId, uri, false), modeFlags, -1);
7204        }
7205    }
7206
7207    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7208            final int modeFlags, UriPermissionOwner owner) {
7209        if (!Intent.isAccessUriMode(modeFlags)) {
7210            return;
7211        }
7212
7213        // So here we are: the caller has the assumed permission
7214        // to the uri, and the target doesn't.  Let's now give this to
7215        // the target.
7216
7217        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7218                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7219
7220        final String authority = grantUri.uri.getAuthority();
7221        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7222        if (pi == null) {
7223            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7224            return;
7225        }
7226
7227        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7228            grantUri.prefix = true;
7229        }
7230        final UriPermission perm = findOrCreateUriPermissionLocked(
7231                pi.packageName, targetPkg, targetUid, grantUri);
7232        perm.grantModes(modeFlags, owner);
7233    }
7234
7235    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7236            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7237        if (targetPkg == null) {
7238            throw new NullPointerException("targetPkg");
7239        }
7240        int targetUid;
7241        final IPackageManager pm = AppGlobals.getPackageManager();
7242        try {
7243            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7244        } catch (RemoteException ex) {
7245            return;
7246        }
7247
7248        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7249                targetUid);
7250        if (targetUid < 0) {
7251            return;
7252        }
7253
7254        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7255                owner);
7256    }
7257
7258    static class NeededUriGrants extends ArrayList<GrantUri> {
7259        final String targetPkg;
7260        final int targetUid;
7261        final int flags;
7262
7263        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7264            this.targetPkg = targetPkg;
7265            this.targetUid = targetUid;
7266            this.flags = flags;
7267        }
7268    }
7269
7270    /**
7271     * Like checkGrantUriPermissionLocked, but takes an Intent.
7272     */
7273    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7274            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7275        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7276                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7277                + " clip=" + (intent != null ? intent.getClipData() : null)
7278                + " from " + intent + "; flags=0x"
7279                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7280
7281        if (targetPkg == null) {
7282            throw new NullPointerException("targetPkg");
7283        }
7284
7285        if (intent == null) {
7286            return null;
7287        }
7288        Uri data = intent.getData();
7289        ClipData clip = intent.getClipData();
7290        if (data == null && clip == null) {
7291            return null;
7292        }
7293        // Default userId for uris in the intent (if they don't specify it themselves)
7294        int contentUserHint = intent.getContentUserHint();
7295        if (contentUserHint == UserHandle.USER_CURRENT) {
7296            contentUserHint = UserHandle.getUserId(callingUid);
7297        }
7298        final IPackageManager pm = AppGlobals.getPackageManager();
7299        int targetUid;
7300        if (needed != null) {
7301            targetUid = needed.targetUid;
7302        } else {
7303            try {
7304                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7305            } catch (RemoteException ex) {
7306                return null;
7307            }
7308            if (targetUid < 0) {
7309                if (DEBUG_URI_PERMISSION) {
7310                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7311                            + " on user " + targetUserId);
7312                }
7313                return null;
7314            }
7315        }
7316        if (data != null) {
7317            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7318            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7319                    targetUid);
7320            if (targetUid > 0) {
7321                if (needed == null) {
7322                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7323                }
7324                needed.add(grantUri);
7325            }
7326        }
7327        if (clip != null) {
7328            for (int i=0; i<clip.getItemCount(); i++) {
7329                Uri uri = clip.getItemAt(i).getUri();
7330                if (uri != null) {
7331                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7332                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7333                            targetUid);
7334                    if (targetUid > 0) {
7335                        if (needed == null) {
7336                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7337                        }
7338                        needed.add(grantUri);
7339                    }
7340                } else {
7341                    Intent clipIntent = clip.getItemAt(i).getIntent();
7342                    if (clipIntent != null) {
7343                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7344                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7345                        if (newNeeded != null) {
7346                            needed = newNeeded;
7347                        }
7348                    }
7349                }
7350            }
7351        }
7352
7353        return needed;
7354    }
7355
7356    /**
7357     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7358     */
7359    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7360            UriPermissionOwner owner) {
7361        if (needed != null) {
7362            for (int i=0; i<needed.size(); i++) {
7363                GrantUri grantUri = needed.get(i);
7364                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7365                        grantUri, needed.flags, owner);
7366            }
7367        }
7368    }
7369
7370    void grantUriPermissionFromIntentLocked(int callingUid,
7371            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7372        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7373                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7374        if (needed == null) {
7375            return;
7376        }
7377
7378        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7379    }
7380
7381    /**
7382     * @param uri This uri must NOT contain an embedded userId.
7383     * @param userId The userId in which the uri is to be resolved.
7384     */
7385    @Override
7386    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7387            final int modeFlags, int userId) {
7388        enforceNotIsolatedCaller("grantUriPermission");
7389        GrantUri grantUri = new GrantUri(userId, uri, false);
7390        synchronized(this) {
7391            final ProcessRecord r = getRecordForAppLocked(caller);
7392            if (r == null) {
7393                throw new SecurityException("Unable to find app for caller "
7394                        + caller
7395                        + " when granting permission to uri " + grantUri);
7396            }
7397            if (targetPkg == null) {
7398                throw new IllegalArgumentException("null target");
7399            }
7400            if (grantUri == null) {
7401                throw new IllegalArgumentException("null uri");
7402            }
7403
7404            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7405                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7406                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7407                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7408
7409            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7410                    UserHandle.getUserId(r.uid));
7411        }
7412    }
7413
7414    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7415        if (perm.modeFlags == 0) {
7416            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7417                    perm.targetUid);
7418            if (perms != null) {
7419                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7420                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7421
7422                perms.remove(perm.uri);
7423                if (perms.isEmpty()) {
7424                    mGrantedUriPermissions.remove(perm.targetUid);
7425                }
7426            }
7427        }
7428    }
7429
7430    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7431        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7432
7433        final IPackageManager pm = AppGlobals.getPackageManager();
7434        final String authority = grantUri.uri.getAuthority();
7435        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7436        if (pi == null) {
7437            Slog.w(TAG, "No content provider found for permission revoke: "
7438                    + grantUri.toSafeString());
7439            return;
7440        }
7441
7442        // Does the caller have this permission on the URI?
7443        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7444            // Right now, if you are not the original owner of the permission,
7445            // you are not allowed to revoke it.
7446            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7447                throw new SecurityException("Uid " + callingUid
7448                        + " does not have permission to uri " + grantUri);
7449            //}
7450        }
7451
7452        boolean persistChanged = false;
7453
7454        // Go through all of the permissions and remove any that match.
7455        int N = mGrantedUriPermissions.size();
7456        for (int i = 0; i < N; i++) {
7457            final int targetUid = mGrantedUriPermissions.keyAt(i);
7458            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7459
7460            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7461                final UriPermission perm = it.next();
7462                if (perm.uri.sourceUserId == grantUri.sourceUserId
7463                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7464                    if (DEBUG_URI_PERMISSION)
7465                        Slog.v(TAG,
7466                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7467                    persistChanged |= perm.revokeModes(
7468                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7469                    if (perm.modeFlags == 0) {
7470                        it.remove();
7471                    }
7472                }
7473            }
7474
7475            if (perms.isEmpty()) {
7476                mGrantedUriPermissions.remove(targetUid);
7477                N--;
7478                i--;
7479            }
7480        }
7481
7482        if (persistChanged) {
7483            schedulePersistUriGrants();
7484        }
7485    }
7486
7487    /**
7488     * @param uri This uri must NOT contain an embedded userId.
7489     * @param userId The userId in which the uri is to be resolved.
7490     */
7491    @Override
7492    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7493            int userId) {
7494        enforceNotIsolatedCaller("revokeUriPermission");
7495        synchronized(this) {
7496            final ProcessRecord r = getRecordForAppLocked(caller);
7497            if (r == null) {
7498                throw new SecurityException("Unable to find app for caller "
7499                        + caller
7500                        + " when revoking permission to uri " + uri);
7501            }
7502            if (uri == null) {
7503                Slog.w(TAG, "revokeUriPermission: null uri");
7504                return;
7505            }
7506
7507            if (!Intent.isAccessUriMode(modeFlags)) {
7508                return;
7509            }
7510
7511            final IPackageManager pm = AppGlobals.getPackageManager();
7512            final String authority = uri.getAuthority();
7513            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7514            if (pi == null) {
7515                Slog.w(TAG, "No content provider found for permission revoke: "
7516                        + uri.toSafeString());
7517                return;
7518            }
7519
7520            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7521        }
7522    }
7523
7524    /**
7525     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7526     * given package.
7527     *
7528     * @param packageName Package name to match, or {@code null} to apply to all
7529     *            packages.
7530     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7531     *            to all users.
7532     * @param persistable If persistable grants should be removed.
7533     */
7534    private void removeUriPermissionsForPackageLocked(
7535            String packageName, int userHandle, boolean persistable) {
7536        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7537            throw new IllegalArgumentException("Must narrow by either package or user");
7538        }
7539
7540        boolean persistChanged = false;
7541
7542        int N = mGrantedUriPermissions.size();
7543        for (int i = 0; i < N; i++) {
7544            final int targetUid = mGrantedUriPermissions.keyAt(i);
7545            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7546
7547            // Only inspect grants matching user
7548            if (userHandle == UserHandle.USER_ALL
7549                    || userHandle == UserHandle.getUserId(targetUid)) {
7550                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7551                    final UriPermission perm = it.next();
7552
7553                    // Only inspect grants matching package
7554                    if (packageName == null || perm.sourcePkg.equals(packageName)
7555                            || perm.targetPkg.equals(packageName)) {
7556                        persistChanged |= perm.revokeModes(
7557                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7558
7559                        // Only remove when no modes remain; any persisted grants
7560                        // will keep this alive.
7561                        if (perm.modeFlags == 0) {
7562                            it.remove();
7563                        }
7564                    }
7565                }
7566
7567                if (perms.isEmpty()) {
7568                    mGrantedUriPermissions.remove(targetUid);
7569                    N--;
7570                    i--;
7571                }
7572            }
7573        }
7574
7575        if (persistChanged) {
7576            schedulePersistUriGrants();
7577        }
7578    }
7579
7580    @Override
7581    public IBinder newUriPermissionOwner(String name) {
7582        enforceNotIsolatedCaller("newUriPermissionOwner");
7583        synchronized(this) {
7584            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7585            return owner.getExternalTokenLocked();
7586        }
7587    }
7588
7589    /**
7590     * @param uri This uri must NOT contain an embedded userId.
7591     * @param sourceUserId The userId in which the uri is to be resolved.
7592     * @param targetUserId The userId of the app that receives the grant.
7593     */
7594    @Override
7595    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7596            final int modeFlags, int sourceUserId, int targetUserId) {
7597        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7598                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7599        synchronized(this) {
7600            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7601            if (owner == null) {
7602                throw new IllegalArgumentException("Unknown owner: " + token);
7603            }
7604            if (fromUid != Binder.getCallingUid()) {
7605                if (Binder.getCallingUid() != Process.myUid()) {
7606                    // Only system code can grant URI permissions on behalf
7607                    // of other users.
7608                    throw new SecurityException("nice try");
7609                }
7610            }
7611            if (targetPkg == null) {
7612                throw new IllegalArgumentException("null target");
7613            }
7614            if (uri == null) {
7615                throw new IllegalArgumentException("null uri");
7616            }
7617
7618            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7619                    modeFlags, owner, targetUserId);
7620        }
7621    }
7622
7623    /**
7624     * @param uri This uri must NOT contain an embedded userId.
7625     * @param userId The userId in which the uri is to be resolved.
7626     */
7627    @Override
7628    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7629        synchronized(this) {
7630            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7631            if (owner == null) {
7632                throw new IllegalArgumentException("Unknown owner: " + token);
7633            }
7634
7635            if (uri == null) {
7636                owner.removeUriPermissionsLocked(mode);
7637            } else {
7638                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7639            }
7640        }
7641    }
7642
7643    private void schedulePersistUriGrants() {
7644        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7645            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7646                    10 * DateUtils.SECOND_IN_MILLIS);
7647        }
7648    }
7649
7650    private void writeGrantedUriPermissions() {
7651        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7652
7653        // Snapshot permissions so we can persist without lock
7654        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7655        synchronized (this) {
7656            final int size = mGrantedUriPermissions.size();
7657            for (int i = 0; i < size; i++) {
7658                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7659                for (UriPermission perm : perms.values()) {
7660                    if (perm.persistedModeFlags != 0) {
7661                        persist.add(perm.snapshot());
7662                    }
7663                }
7664            }
7665        }
7666
7667        FileOutputStream fos = null;
7668        try {
7669            fos = mGrantFile.startWrite();
7670
7671            XmlSerializer out = new FastXmlSerializer();
7672            out.setOutput(fos, "utf-8");
7673            out.startDocument(null, true);
7674            out.startTag(null, TAG_URI_GRANTS);
7675            for (UriPermission.Snapshot perm : persist) {
7676                out.startTag(null, TAG_URI_GRANT);
7677                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7678                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7679                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7680                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7681                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7682                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7683                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7684                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7685                out.endTag(null, TAG_URI_GRANT);
7686            }
7687            out.endTag(null, TAG_URI_GRANTS);
7688            out.endDocument();
7689
7690            mGrantFile.finishWrite(fos);
7691        } catch (IOException e) {
7692            if (fos != null) {
7693                mGrantFile.failWrite(fos);
7694            }
7695        }
7696    }
7697
7698    private void readGrantedUriPermissionsLocked() {
7699        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7700
7701        final long now = System.currentTimeMillis();
7702
7703        FileInputStream fis = null;
7704        try {
7705            fis = mGrantFile.openRead();
7706            final XmlPullParser in = Xml.newPullParser();
7707            in.setInput(fis, null);
7708
7709            int type;
7710            while ((type = in.next()) != END_DOCUMENT) {
7711                final String tag = in.getName();
7712                if (type == START_TAG) {
7713                    if (TAG_URI_GRANT.equals(tag)) {
7714                        final int sourceUserId;
7715                        final int targetUserId;
7716                        final int userHandle = readIntAttribute(in,
7717                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7718                        if (userHandle != UserHandle.USER_NULL) {
7719                            // For backwards compatibility.
7720                            sourceUserId = userHandle;
7721                            targetUserId = userHandle;
7722                        } else {
7723                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7724                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7725                        }
7726                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7727                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7728                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7729                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7730                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7731                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7732
7733                        // Sanity check that provider still belongs to source package
7734                        final ProviderInfo pi = getProviderInfoLocked(
7735                                uri.getAuthority(), sourceUserId);
7736                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7737                            int targetUid = -1;
7738                            try {
7739                                targetUid = AppGlobals.getPackageManager()
7740                                        .getPackageUid(targetPkg, targetUserId);
7741                            } catch (RemoteException e) {
7742                            }
7743                            if (targetUid != -1) {
7744                                final UriPermission perm = findOrCreateUriPermissionLocked(
7745                                        sourcePkg, targetPkg, targetUid,
7746                                        new GrantUri(sourceUserId, uri, prefix));
7747                                perm.initPersistedModes(modeFlags, createdTime);
7748                            }
7749                        } else {
7750                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7751                                    + " but instead found " + pi);
7752                        }
7753                    }
7754                }
7755            }
7756        } catch (FileNotFoundException e) {
7757            // Missing grants is okay
7758        } catch (IOException e) {
7759            Log.wtf(TAG, "Failed reading Uri grants", e);
7760        } catch (XmlPullParserException e) {
7761            Log.wtf(TAG, "Failed reading Uri grants", e);
7762        } finally {
7763            IoUtils.closeQuietly(fis);
7764        }
7765    }
7766
7767    /**
7768     * @param uri This uri must NOT contain an embedded userId.
7769     * @param userId The userId in which the uri is to be resolved.
7770     */
7771    @Override
7772    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7773        enforceNotIsolatedCaller("takePersistableUriPermission");
7774
7775        Preconditions.checkFlagsArgument(modeFlags,
7776                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7777
7778        synchronized (this) {
7779            final int callingUid = Binder.getCallingUid();
7780            boolean persistChanged = false;
7781            GrantUri grantUri = new GrantUri(userId, uri, false);
7782
7783            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7784                    new GrantUri(userId, uri, false));
7785            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7786                    new GrantUri(userId, uri, true));
7787
7788            final boolean exactValid = (exactPerm != null)
7789                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7790            final boolean prefixValid = (prefixPerm != null)
7791                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7792
7793            if (!(exactValid || prefixValid)) {
7794                throw new SecurityException("No persistable permission grants found for UID "
7795                        + callingUid + " and Uri " + grantUri.toSafeString());
7796            }
7797
7798            if (exactValid) {
7799                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7800            }
7801            if (prefixValid) {
7802                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7803            }
7804
7805            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7806
7807            if (persistChanged) {
7808                schedulePersistUriGrants();
7809            }
7810        }
7811    }
7812
7813    /**
7814     * @param uri This uri must NOT contain an embedded userId.
7815     * @param userId The userId in which the uri is to be resolved.
7816     */
7817    @Override
7818    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7819        enforceNotIsolatedCaller("releasePersistableUriPermission");
7820
7821        Preconditions.checkFlagsArgument(modeFlags,
7822                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7823
7824        synchronized (this) {
7825            final int callingUid = Binder.getCallingUid();
7826            boolean persistChanged = false;
7827
7828            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7829                    new GrantUri(userId, uri, false));
7830            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7831                    new GrantUri(userId, uri, true));
7832            if (exactPerm == null && prefixPerm == null) {
7833                throw new SecurityException("No permission grants found for UID " + callingUid
7834                        + " and Uri " + uri.toSafeString());
7835            }
7836
7837            if (exactPerm != null) {
7838                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7839                removeUriPermissionIfNeededLocked(exactPerm);
7840            }
7841            if (prefixPerm != null) {
7842                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7843                removeUriPermissionIfNeededLocked(prefixPerm);
7844            }
7845
7846            if (persistChanged) {
7847                schedulePersistUriGrants();
7848            }
7849        }
7850    }
7851
7852    /**
7853     * Prune any older {@link UriPermission} for the given UID until outstanding
7854     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7855     *
7856     * @return if any mutations occured that require persisting.
7857     */
7858    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7859        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7860        if (perms == null) return false;
7861        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7862
7863        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7864        for (UriPermission perm : perms.values()) {
7865            if (perm.persistedModeFlags != 0) {
7866                persisted.add(perm);
7867            }
7868        }
7869
7870        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7871        if (trimCount <= 0) return false;
7872
7873        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7874        for (int i = 0; i < trimCount; i++) {
7875            final UriPermission perm = persisted.get(i);
7876
7877            if (DEBUG_URI_PERMISSION) {
7878                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7879            }
7880
7881            perm.releasePersistableModes(~0);
7882            removeUriPermissionIfNeededLocked(perm);
7883        }
7884
7885        return true;
7886    }
7887
7888    @Override
7889    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7890            String packageName, boolean incoming) {
7891        enforceNotIsolatedCaller("getPersistedUriPermissions");
7892        Preconditions.checkNotNull(packageName, "packageName");
7893
7894        final int callingUid = Binder.getCallingUid();
7895        final IPackageManager pm = AppGlobals.getPackageManager();
7896        try {
7897            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7898            if (packageUid != callingUid) {
7899                throw new SecurityException(
7900                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7901            }
7902        } catch (RemoteException e) {
7903            throw new SecurityException("Failed to verify package name ownership");
7904        }
7905
7906        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7907        synchronized (this) {
7908            if (incoming) {
7909                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7910                        callingUid);
7911                if (perms == null) {
7912                    Slog.w(TAG, "No permission grants found for " + packageName);
7913                } else {
7914                    for (UriPermission perm : perms.values()) {
7915                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7916                            result.add(perm.buildPersistedPublicApiObject());
7917                        }
7918                    }
7919                }
7920            } else {
7921                final int size = mGrantedUriPermissions.size();
7922                for (int i = 0; i < size; i++) {
7923                    final ArrayMap<GrantUri, UriPermission> perms =
7924                            mGrantedUriPermissions.valueAt(i);
7925                    for (UriPermission perm : perms.values()) {
7926                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7927                            result.add(perm.buildPersistedPublicApiObject());
7928                        }
7929                    }
7930                }
7931            }
7932        }
7933        return new ParceledListSlice<android.content.UriPermission>(result);
7934    }
7935
7936    @Override
7937    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7938        synchronized (this) {
7939            ProcessRecord app =
7940                who != null ? getRecordForAppLocked(who) : null;
7941            if (app == null) return;
7942
7943            Message msg = Message.obtain();
7944            msg.what = WAIT_FOR_DEBUGGER_MSG;
7945            msg.obj = app;
7946            msg.arg1 = waiting ? 1 : 0;
7947            mHandler.sendMessage(msg);
7948        }
7949    }
7950
7951    @Override
7952    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7953        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7954        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7955        outInfo.availMem = Process.getFreeMemory();
7956        outInfo.totalMem = Process.getTotalMemory();
7957        outInfo.threshold = homeAppMem;
7958        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7959        outInfo.hiddenAppThreshold = cachedAppMem;
7960        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7961                ProcessList.SERVICE_ADJ);
7962        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7963                ProcessList.VISIBLE_APP_ADJ);
7964        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7965                ProcessList.FOREGROUND_APP_ADJ);
7966    }
7967
7968    // =========================================================
7969    // TASK MANAGEMENT
7970    // =========================================================
7971
7972    @Override
7973    public List<IAppTask> getAppTasks(String callingPackage) {
7974        int callingUid = Binder.getCallingUid();
7975        long ident = Binder.clearCallingIdentity();
7976
7977        synchronized(this) {
7978            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7979            try {
7980                if (localLOGV) Slog.v(TAG, "getAppTasks");
7981
7982                final int N = mRecentTasks.size();
7983                for (int i = 0; i < N; i++) {
7984                    TaskRecord tr = mRecentTasks.get(i);
7985                    // Skip tasks that do not match the caller.  We don't need to verify
7986                    // callingPackage, because we are also limiting to callingUid and know
7987                    // that will limit to the correct security sandbox.
7988                    if (tr.effectiveUid != callingUid) {
7989                        continue;
7990                    }
7991                    Intent intent = tr.getBaseIntent();
7992                    if (intent == null ||
7993                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7994                        continue;
7995                    }
7996                    ActivityManager.RecentTaskInfo taskInfo =
7997                            createRecentTaskInfoFromTaskRecord(tr);
7998                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7999                    list.add(taskImpl);
8000                }
8001            } finally {
8002                Binder.restoreCallingIdentity(ident);
8003            }
8004            return list;
8005        }
8006    }
8007
8008    @Override
8009    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8010        final int callingUid = Binder.getCallingUid();
8011        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8012
8013        synchronized(this) {
8014            if (localLOGV) Slog.v(
8015                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8016
8017            final boolean allowed = checkCallingPermission(
8018                    android.Manifest.permission.GET_TASKS)
8019                    == PackageManager.PERMISSION_GRANTED;
8020            if (!allowed) {
8021                Slog.w(TAG, "getTasks: caller " + callingUid
8022                        + " does not hold GET_TASKS; limiting output");
8023            }
8024
8025            // TODO: Improve with MRU list from all ActivityStacks.
8026            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8027        }
8028
8029        return list;
8030    }
8031
8032    TaskRecord getMostRecentTask() {
8033        return mRecentTasks.get(0);
8034    }
8035
8036    /**
8037     * Creates a new RecentTaskInfo from a TaskRecord.
8038     */
8039    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8040        // Update the task description to reflect any changes in the task stack
8041        tr.updateTaskDescription();
8042
8043        // Compose the recent task info
8044        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8045        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8046        rti.persistentId = tr.taskId;
8047        rti.baseIntent = new Intent(tr.getBaseIntent());
8048        rti.origActivity = tr.origActivity;
8049        rti.description = tr.lastDescription;
8050        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8051        rti.userId = tr.userId;
8052        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8053        rti.firstActiveTime = tr.firstActiveTime;
8054        rti.lastActiveTime = tr.lastActiveTime;
8055        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8056        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8057        return rti;
8058    }
8059
8060    @Override
8061    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8062        final int callingUid = Binder.getCallingUid();
8063        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8064                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8065
8066        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8067        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8068        synchronized (this) {
8069            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8070                    == PackageManager.PERMISSION_GRANTED;
8071            if (!allowed) {
8072                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8073                        + " does not hold GET_TASKS; limiting output");
8074            }
8075            final boolean detailed = checkCallingPermission(
8076                    android.Manifest.permission.GET_DETAILED_TASKS)
8077                    == PackageManager.PERMISSION_GRANTED;
8078
8079            final int N = mRecentTasks.size();
8080            ArrayList<ActivityManager.RecentTaskInfo> res
8081                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8082                            maxNum < N ? maxNum : N);
8083
8084            final Set<Integer> includedUsers;
8085            if (includeProfiles) {
8086                includedUsers = getProfileIdsLocked(userId);
8087            } else {
8088                includedUsers = new HashSet<Integer>();
8089            }
8090            includedUsers.add(Integer.valueOf(userId));
8091
8092            for (int i=0; i<N && maxNum > 0; i++) {
8093                TaskRecord tr = mRecentTasks.get(i);
8094                // Only add calling user or related users recent tasks
8095                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8096                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8097                    continue;
8098                }
8099
8100                // Return the entry if desired by the caller.  We always return
8101                // the first entry, because callers always expect this to be the
8102                // foreground app.  We may filter others if the caller has
8103                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8104                // we should exclude the entry.
8105
8106                if (i == 0
8107                        || withExcluded
8108                        || (tr.intent == null)
8109                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8110                                == 0)) {
8111                    if (!allowed) {
8112                        // If the caller doesn't have the GET_TASKS permission, then only
8113                        // allow them to see a small subset of tasks -- their own and home.
8114                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8115                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8116                            continue;
8117                        }
8118                    }
8119                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8120                        if (tr.stack != null && tr.stack.isHomeStack()) {
8121                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8122                            continue;
8123                        }
8124                    }
8125                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8126                        // Don't include auto remove tasks that are finished or finishing.
8127                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8128                                + tr);
8129                        continue;
8130                    }
8131                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8132                            && !tr.isAvailable) {
8133                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8134                        continue;
8135                    }
8136
8137                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8138                    if (!detailed) {
8139                        rti.baseIntent.replaceExtras((Bundle)null);
8140                    }
8141
8142                    res.add(rti);
8143                    maxNum--;
8144                }
8145            }
8146            return res;
8147        }
8148    }
8149
8150    private TaskRecord recentTaskForIdLocked(int id) {
8151        final int N = mRecentTasks.size();
8152            for (int i=0; i<N; i++) {
8153                TaskRecord tr = mRecentTasks.get(i);
8154                if (tr.taskId == id) {
8155                    return tr;
8156                }
8157            }
8158            return null;
8159    }
8160
8161    @Override
8162    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8163        synchronized (this) {
8164            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8165                    "getTaskThumbnail()");
8166            TaskRecord tr = recentTaskForIdLocked(id);
8167            if (tr != null) {
8168                return tr.getTaskThumbnailLocked();
8169            }
8170        }
8171        return null;
8172    }
8173
8174    @Override
8175    public int addAppTask(IBinder activityToken, Intent intent,
8176            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8177        final int callingUid = Binder.getCallingUid();
8178        final long callingIdent = Binder.clearCallingIdentity();
8179
8180        try {
8181            synchronized (this) {
8182                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8183                if (r == null) {
8184                    throw new IllegalArgumentException("Activity does not exist; token="
8185                            + activityToken);
8186                }
8187                ComponentName comp = intent.getComponent();
8188                if (comp == null) {
8189                    throw new IllegalArgumentException("Intent " + intent
8190                            + " must specify explicit component");
8191                }
8192                if (thumbnail.getWidth() != mThumbnailWidth
8193                        || thumbnail.getHeight() != mThumbnailHeight) {
8194                    throw new IllegalArgumentException("Bad thumbnail size: got "
8195                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8196                            + mThumbnailWidth + "x" + mThumbnailHeight);
8197                }
8198                if (intent.getSelector() != null) {
8199                    intent.setSelector(null);
8200                }
8201                if (intent.getSourceBounds() != null) {
8202                    intent.setSourceBounds(null);
8203                }
8204                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8205                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8206                        // The caller has added this as an auto-remove task...  that makes no
8207                        // sense, so turn off auto-remove.
8208                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8209                    }
8210                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8211                    // Must be a new task.
8212                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8213                }
8214                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8215                    mLastAddedTaskActivity = null;
8216                }
8217                ActivityInfo ainfo = mLastAddedTaskActivity;
8218                if (ainfo == null) {
8219                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8220                            comp, 0, UserHandle.getUserId(callingUid));
8221                    if (ainfo.applicationInfo.uid != callingUid) {
8222                        throw new SecurityException(
8223                                "Can't add task for another application: target uid="
8224                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8225                    }
8226                }
8227
8228                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8229                        intent, description);
8230
8231                int trimIdx = trimRecentsForTask(task, false);
8232                if (trimIdx >= 0) {
8233                    // If this would have caused a trim, then we'll abort because that
8234                    // means it would be added at the end of the list but then just removed.
8235                    return -1;
8236                }
8237
8238                final int N = mRecentTasks.size();
8239                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8240                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8241                    tr.removedFromRecents(mTaskPersister);
8242                }
8243
8244                task.inRecents = true;
8245                mRecentTasks.add(task);
8246                r.task.stack.addTask(task, false, false);
8247
8248                task.setLastThumbnail(thumbnail);
8249                task.freeLastThumbnail();
8250
8251                return task.taskId;
8252            }
8253        } finally {
8254            Binder.restoreCallingIdentity(callingIdent);
8255        }
8256    }
8257
8258    @Override
8259    public Point getAppTaskThumbnailSize() {
8260        synchronized (this) {
8261            return new Point(mThumbnailWidth,  mThumbnailHeight);
8262        }
8263    }
8264
8265    @Override
8266    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8267        synchronized (this) {
8268            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8269            if (r != null) {
8270                r.taskDescription = td;
8271                r.task.updateTaskDescription();
8272            }
8273        }
8274    }
8275
8276    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8277        mRecentTasks.remove(tr);
8278        tr.removedFromRecents(mTaskPersister);
8279        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8280        Intent baseIntent = new Intent(
8281                tr.intent != null ? tr.intent : tr.affinityIntent);
8282        ComponentName component = baseIntent.getComponent();
8283        if (component == null) {
8284            Slog.w(TAG, "Now component for base intent of task: " + tr);
8285            return;
8286        }
8287
8288        // Find any running services associated with this app.
8289        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8290
8291        if (killProcesses) {
8292            // Find any running processes associated with this app.
8293            final String pkg = component.getPackageName();
8294            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8295            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8296            for (int i=0; i<pmap.size(); i++) {
8297                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8298                for (int j=0; j<uids.size(); j++) {
8299                    ProcessRecord proc = uids.valueAt(j);
8300                    if (proc.userId != tr.userId) {
8301                        continue;
8302                    }
8303                    if (!proc.pkgList.containsKey(pkg)) {
8304                        continue;
8305                    }
8306                    procs.add(proc);
8307                }
8308            }
8309
8310            // Kill the running processes.
8311            for (int i=0; i<procs.size(); i++) {
8312                ProcessRecord pr = procs.get(i);
8313                if (pr == mHomeProcess) {
8314                    // Don't kill the home process along with tasks from the same package.
8315                    continue;
8316                }
8317                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8318                    pr.kill("remove task", true);
8319                } else {
8320                    pr.waitingToKill = "remove task";
8321                }
8322            }
8323        }
8324    }
8325
8326    /**
8327     * Removes the task with the specified task id.
8328     *
8329     * @param taskId Identifier of the task to be removed.
8330     * @param flags Additional operational flags.  May be 0 or
8331     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8332     * @return Returns true if the given task was found and removed.
8333     */
8334    private boolean removeTaskByIdLocked(int taskId, int flags) {
8335        TaskRecord tr = recentTaskForIdLocked(taskId);
8336        if (tr != null) {
8337            tr.removeTaskActivitiesLocked();
8338            cleanUpRemovedTaskLocked(tr, flags);
8339            if (tr.isPersistable) {
8340                notifyTaskPersisterLocked(null, true);
8341            }
8342            return true;
8343        }
8344        return false;
8345    }
8346
8347    @Override
8348    public boolean removeTask(int taskId, int flags) {
8349        synchronized (this) {
8350            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8351                    "removeTask()");
8352            long ident = Binder.clearCallingIdentity();
8353            try {
8354                return removeTaskByIdLocked(taskId, flags);
8355            } finally {
8356                Binder.restoreCallingIdentity(ident);
8357            }
8358        }
8359    }
8360
8361    /**
8362     * TODO: Add mController hook
8363     */
8364    @Override
8365    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8366        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8367                "moveTaskToFront()");
8368
8369        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8370        synchronized(this) {
8371            moveTaskToFrontLocked(taskId, flags, options);
8372        }
8373    }
8374
8375    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8376        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8377                Binder.getCallingUid(), "Task to front")) {
8378            ActivityOptions.abort(options);
8379            return;
8380        }
8381        final long origId = Binder.clearCallingIdentity();
8382        try {
8383            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8384            if (task == null) {
8385                return;
8386            }
8387            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8388                mStackSupervisor.showLockTaskToast();
8389                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8390                return;
8391            }
8392            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8393            if (prev != null && prev.isRecentsActivity()) {
8394                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8395            }
8396            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8397        } finally {
8398            Binder.restoreCallingIdentity(origId);
8399        }
8400        ActivityOptions.abort(options);
8401    }
8402
8403    @Override
8404    public void moveTaskToBack(int taskId) {
8405        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8406                "moveTaskToBack()");
8407
8408        synchronized(this) {
8409            TaskRecord tr = recentTaskForIdLocked(taskId);
8410            if (tr != null) {
8411                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8412                ActivityStack stack = tr.stack;
8413                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8414                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8415                            Binder.getCallingUid(), "Task to back")) {
8416                        return;
8417                    }
8418                }
8419                final long origId = Binder.clearCallingIdentity();
8420                try {
8421                    stack.moveTaskToBackLocked(taskId, null);
8422                } finally {
8423                    Binder.restoreCallingIdentity(origId);
8424                }
8425            }
8426        }
8427    }
8428
8429    /**
8430     * Moves an activity, and all of the other activities within the same task, to the bottom
8431     * of the history stack.  The activity's order within the task is unchanged.
8432     *
8433     * @param token A reference to the activity we wish to move
8434     * @param nonRoot If false then this only works if the activity is the root
8435     *                of a task; if true it will work for any activity in a task.
8436     * @return Returns true if the move completed, false if not.
8437     */
8438    @Override
8439    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8440        enforceNotIsolatedCaller("moveActivityTaskToBack");
8441        synchronized(this) {
8442            final long origId = Binder.clearCallingIdentity();
8443            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8444            if (taskId >= 0) {
8445                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8446            }
8447            Binder.restoreCallingIdentity(origId);
8448        }
8449        return false;
8450    }
8451
8452    @Override
8453    public void moveTaskBackwards(int task) {
8454        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8455                "moveTaskBackwards()");
8456
8457        synchronized(this) {
8458            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8459                    Binder.getCallingUid(), "Task backwards")) {
8460                return;
8461            }
8462            final long origId = Binder.clearCallingIdentity();
8463            moveTaskBackwardsLocked(task);
8464            Binder.restoreCallingIdentity(origId);
8465        }
8466    }
8467
8468    private final void moveTaskBackwardsLocked(int task) {
8469        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8470    }
8471
8472    @Override
8473    public IBinder getHomeActivityToken() throws RemoteException {
8474        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8475                "getHomeActivityToken()");
8476        synchronized (this) {
8477            return mStackSupervisor.getHomeActivityToken();
8478        }
8479    }
8480
8481    @Override
8482    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8483            IActivityContainerCallback callback) throws RemoteException {
8484        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8485                "createActivityContainer()");
8486        synchronized (this) {
8487            if (parentActivityToken == null) {
8488                throw new IllegalArgumentException("parent token must not be null");
8489            }
8490            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8491            if (r == null) {
8492                return null;
8493            }
8494            if (callback == null) {
8495                throw new IllegalArgumentException("callback must not be null");
8496            }
8497            return mStackSupervisor.createActivityContainer(r, callback);
8498        }
8499    }
8500
8501    @Override
8502    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8503        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8504                "deleteActivityContainer()");
8505        synchronized (this) {
8506            mStackSupervisor.deleteActivityContainer(container);
8507        }
8508    }
8509
8510    @Override
8511    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8512            throws RemoteException {
8513        synchronized (this) {
8514            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8515            if (stack != null) {
8516                return stack.mActivityContainer;
8517            }
8518            return null;
8519        }
8520    }
8521
8522    @Override
8523    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8524        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8525                "moveTaskToStack()");
8526        if (stackId == HOME_STACK_ID) {
8527            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8528                    new RuntimeException("here").fillInStackTrace());
8529        }
8530        synchronized (this) {
8531            long ident = Binder.clearCallingIdentity();
8532            try {
8533                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8534                        + stackId + " toTop=" + toTop);
8535                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8536            } finally {
8537                Binder.restoreCallingIdentity(ident);
8538            }
8539        }
8540    }
8541
8542    @Override
8543    public void resizeStack(int stackBoxId, Rect bounds) {
8544        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8545                "resizeStackBox()");
8546        long ident = Binder.clearCallingIdentity();
8547        try {
8548            mWindowManager.resizeStack(stackBoxId, bounds);
8549        } finally {
8550            Binder.restoreCallingIdentity(ident);
8551        }
8552    }
8553
8554    @Override
8555    public List<StackInfo> getAllStackInfos() {
8556        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8557                "getAllStackInfos()");
8558        long ident = Binder.clearCallingIdentity();
8559        try {
8560            synchronized (this) {
8561                return mStackSupervisor.getAllStackInfosLocked();
8562            }
8563        } finally {
8564            Binder.restoreCallingIdentity(ident);
8565        }
8566    }
8567
8568    @Override
8569    public StackInfo getStackInfo(int stackId) {
8570        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8571                "getStackInfo()");
8572        long ident = Binder.clearCallingIdentity();
8573        try {
8574            synchronized (this) {
8575                return mStackSupervisor.getStackInfoLocked(stackId);
8576            }
8577        } finally {
8578            Binder.restoreCallingIdentity(ident);
8579        }
8580    }
8581
8582    @Override
8583    public boolean isInHomeStack(int taskId) {
8584        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8585                "getStackInfo()");
8586        long ident = Binder.clearCallingIdentity();
8587        try {
8588            synchronized (this) {
8589                TaskRecord tr = recentTaskForIdLocked(taskId);
8590                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8591            }
8592        } finally {
8593            Binder.restoreCallingIdentity(ident);
8594        }
8595    }
8596
8597    @Override
8598    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8599        synchronized(this) {
8600            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8601        }
8602    }
8603
8604    private boolean isLockTaskAuthorized(String pkg) {
8605        final DevicePolicyManager dpm = (DevicePolicyManager)
8606                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8607        try {
8608            int uid = mContext.getPackageManager().getPackageUid(pkg,
8609                    Binder.getCallingUserHandle().getIdentifier());
8610            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8611        } catch (NameNotFoundException e) {
8612            return false;
8613        }
8614    }
8615
8616    void startLockTaskMode(TaskRecord task) {
8617        final String pkg;
8618        synchronized (this) {
8619            pkg = task.intent.getComponent().getPackageName();
8620        }
8621        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8622        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8623            final TaskRecord taskRecord = task;
8624            mHandler.post(new Runnable() {
8625                @Override
8626                public void run() {
8627                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8628                }
8629            });
8630            return;
8631        }
8632        long ident = Binder.clearCallingIdentity();
8633        try {
8634            synchronized (this) {
8635                // Since we lost lock on task, make sure it is still there.
8636                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8637                if (task != null) {
8638                    if (!isSystemInitiated
8639                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8640                        throw new IllegalArgumentException("Invalid task, not in foreground");
8641                    }
8642                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8643                }
8644            }
8645        } finally {
8646            Binder.restoreCallingIdentity(ident);
8647        }
8648    }
8649
8650    @Override
8651    public void startLockTaskMode(int taskId) {
8652        final TaskRecord task;
8653        long ident = Binder.clearCallingIdentity();
8654        try {
8655            synchronized (this) {
8656                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8657            }
8658        } finally {
8659            Binder.restoreCallingIdentity(ident);
8660        }
8661        if (task != null) {
8662            startLockTaskMode(task);
8663        }
8664    }
8665
8666    @Override
8667    public void startLockTaskMode(IBinder token) {
8668        final TaskRecord task;
8669        long ident = Binder.clearCallingIdentity();
8670        try {
8671            synchronized (this) {
8672                final ActivityRecord r = ActivityRecord.forToken(token);
8673                if (r == null) {
8674                    return;
8675                }
8676                task = r.task;
8677            }
8678        } finally {
8679            Binder.restoreCallingIdentity(ident);
8680        }
8681        if (task != null) {
8682            startLockTaskMode(task);
8683        }
8684    }
8685
8686    @Override
8687    public void startLockTaskModeOnCurrent() throws RemoteException {
8688        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8689        ActivityRecord r = null;
8690        synchronized (this) {
8691            r = mStackSupervisor.topRunningActivityLocked();
8692        }
8693        startLockTaskMode(r.task);
8694    }
8695
8696    @Override
8697    public void stopLockTaskMode() {
8698        // Verify that the user matches the package of the intent for the TaskRecord
8699        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8700        // and stopLockTaskMode.
8701        final int callingUid = Binder.getCallingUid();
8702        if (callingUid != Process.SYSTEM_UID) {
8703            try {
8704                String pkg =
8705                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8706                int uid = mContext.getPackageManager().getPackageUid(pkg,
8707                        Binder.getCallingUserHandle().getIdentifier());
8708                if (uid != callingUid) {
8709                    throw new SecurityException("Invalid uid, expected " + uid);
8710                }
8711            } catch (NameNotFoundException e) {
8712                Log.d(TAG, "stopLockTaskMode " + e);
8713                return;
8714            }
8715        }
8716        long ident = Binder.clearCallingIdentity();
8717        try {
8718            Log.d(TAG, "stopLockTaskMode");
8719            // Stop lock task
8720            synchronized (this) {
8721                mStackSupervisor.setLockTaskModeLocked(null, false);
8722            }
8723        } finally {
8724            Binder.restoreCallingIdentity(ident);
8725        }
8726    }
8727
8728    @Override
8729    public void stopLockTaskModeOnCurrent() throws RemoteException {
8730        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8731        long ident = Binder.clearCallingIdentity();
8732        try {
8733            stopLockTaskMode();
8734        } finally {
8735            Binder.restoreCallingIdentity(ident);
8736        }
8737    }
8738
8739    @Override
8740    public boolean isInLockTaskMode() {
8741        synchronized (this) {
8742            return mStackSupervisor.isInLockTaskMode();
8743        }
8744    }
8745
8746    // =========================================================
8747    // CONTENT PROVIDERS
8748    // =========================================================
8749
8750    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8751        List<ProviderInfo> providers = null;
8752        try {
8753            providers = AppGlobals.getPackageManager().
8754                queryContentProviders(app.processName, app.uid,
8755                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8756        } catch (RemoteException ex) {
8757        }
8758        if (DEBUG_MU)
8759            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8760        int userId = app.userId;
8761        if (providers != null) {
8762            int N = providers.size();
8763            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8764            for (int i=0; i<N; i++) {
8765                ProviderInfo cpi =
8766                    (ProviderInfo)providers.get(i);
8767                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8768                        cpi.name, cpi.flags);
8769                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8770                    // This is a singleton provider, but a user besides the
8771                    // default user is asking to initialize a process it runs
8772                    // in...  well, no, it doesn't actually run in this process,
8773                    // it runs in the process of the default user.  Get rid of it.
8774                    providers.remove(i);
8775                    N--;
8776                    i--;
8777                    continue;
8778                }
8779
8780                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8781                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8782                if (cpr == null) {
8783                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8784                    mProviderMap.putProviderByClass(comp, cpr);
8785                }
8786                if (DEBUG_MU)
8787                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8788                app.pubProviders.put(cpi.name, cpr);
8789                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8790                    // Don't add this if it is a platform component that is marked
8791                    // to run in multiple processes, because this is actually
8792                    // part of the framework so doesn't make sense to track as a
8793                    // separate apk in the process.
8794                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8795                            mProcessStats);
8796                }
8797                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8798            }
8799        }
8800        return providers;
8801    }
8802
8803    /**
8804     * Check if {@link ProcessRecord} has a possible chance at accessing the
8805     * given {@link ProviderInfo}. Final permission checking is always done
8806     * in {@link ContentProvider}.
8807     */
8808    private final String checkContentProviderPermissionLocked(
8809            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8810        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8811        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8812        boolean checkedGrants = false;
8813        if (checkUser) {
8814            // Looking for cross-user grants before enforcing the typical cross-users permissions
8815            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8816            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8817                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8818                    return null;
8819                }
8820                checkedGrants = true;
8821            }
8822            userId = handleIncomingUser(callingPid, callingUid, userId,
8823                    false, ALLOW_NON_FULL,
8824                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8825            if (userId != tmpTargetUserId) {
8826                // When we actually went to determine the final targer user ID, this ended
8827                // up different than our initial check for the authority.  This is because
8828                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8829                // SELF.  So we need to re-check the grants again.
8830                checkedGrants = false;
8831            }
8832        }
8833        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8834                cpi.applicationInfo.uid, cpi.exported)
8835                == PackageManager.PERMISSION_GRANTED) {
8836            return null;
8837        }
8838        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8839                cpi.applicationInfo.uid, cpi.exported)
8840                == PackageManager.PERMISSION_GRANTED) {
8841            return null;
8842        }
8843
8844        PathPermission[] pps = cpi.pathPermissions;
8845        if (pps != null) {
8846            int i = pps.length;
8847            while (i > 0) {
8848                i--;
8849                PathPermission pp = pps[i];
8850                String pprperm = pp.getReadPermission();
8851                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8852                        cpi.applicationInfo.uid, cpi.exported)
8853                        == PackageManager.PERMISSION_GRANTED) {
8854                    return null;
8855                }
8856                String ppwperm = pp.getWritePermission();
8857                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8858                        cpi.applicationInfo.uid, cpi.exported)
8859                        == PackageManager.PERMISSION_GRANTED) {
8860                    return null;
8861                }
8862            }
8863        }
8864        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8865            return null;
8866        }
8867
8868        String msg;
8869        if (!cpi.exported) {
8870            msg = "Permission Denial: opening provider " + cpi.name
8871                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8872                    + ", uid=" + callingUid + ") that is not exported from uid "
8873                    + cpi.applicationInfo.uid;
8874        } else {
8875            msg = "Permission Denial: opening provider " + cpi.name
8876                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8877                    + ", uid=" + callingUid + ") requires "
8878                    + cpi.readPermission + " or " + cpi.writePermission;
8879        }
8880        Slog.w(TAG, msg);
8881        return msg;
8882    }
8883
8884    /**
8885     * Returns if the ContentProvider has granted a uri to callingUid
8886     */
8887    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8888        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8889        if (perms != null) {
8890            for (int i=perms.size()-1; i>=0; i--) {
8891                GrantUri grantUri = perms.keyAt(i);
8892                if (grantUri.sourceUserId == userId || !checkUser) {
8893                    if (matchesProvider(grantUri.uri, cpi)) {
8894                        return true;
8895                    }
8896                }
8897            }
8898        }
8899        return false;
8900    }
8901
8902    /**
8903     * Returns true if the uri authority is one of the authorities specified in the provider.
8904     */
8905    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8906        String uriAuth = uri.getAuthority();
8907        String cpiAuth = cpi.authority;
8908        if (cpiAuth.indexOf(';') == -1) {
8909            return cpiAuth.equals(uriAuth);
8910        }
8911        String[] cpiAuths = cpiAuth.split(";");
8912        int length = cpiAuths.length;
8913        for (int i = 0; i < length; i++) {
8914            if (cpiAuths[i].equals(uriAuth)) return true;
8915        }
8916        return false;
8917    }
8918
8919    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8920            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8921        if (r != null) {
8922            for (int i=0; i<r.conProviders.size(); i++) {
8923                ContentProviderConnection conn = r.conProviders.get(i);
8924                if (conn.provider == cpr) {
8925                    if (DEBUG_PROVIDER) Slog.v(TAG,
8926                            "Adding provider requested by "
8927                            + r.processName + " from process "
8928                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8929                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8930                    if (stable) {
8931                        conn.stableCount++;
8932                        conn.numStableIncs++;
8933                    } else {
8934                        conn.unstableCount++;
8935                        conn.numUnstableIncs++;
8936                    }
8937                    return conn;
8938                }
8939            }
8940            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8941            if (stable) {
8942                conn.stableCount = 1;
8943                conn.numStableIncs = 1;
8944            } else {
8945                conn.unstableCount = 1;
8946                conn.numUnstableIncs = 1;
8947            }
8948            cpr.connections.add(conn);
8949            r.conProviders.add(conn);
8950            return conn;
8951        }
8952        cpr.addExternalProcessHandleLocked(externalProcessToken);
8953        return null;
8954    }
8955
8956    boolean decProviderCountLocked(ContentProviderConnection conn,
8957            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8958        if (conn != null) {
8959            cpr = conn.provider;
8960            if (DEBUG_PROVIDER) Slog.v(TAG,
8961                    "Removing provider requested by "
8962                    + conn.client.processName + " from process "
8963                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8964                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8965            if (stable) {
8966                conn.stableCount--;
8967            } else {
8968                conn.unstableCount--;
8969            }
8970            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8971                cpr.connections.remove(conn);
8972                conn.client.conProviders.remove(conn);
8973                return true;
8974            }
8975            return false;
8976        }
8977        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8978        return false;
8979    }
8980
8981    private void checkTime(long startTime, String where) {
8982        long now = SystemClock.elapsedRealtime();
8983        if ((now-startTime) > 1000) {
8984            // If we are taking more than a second, log about it.
8985            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8986        }
8987    }
8988
8989    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8990            String name, IBinder token, boolean stable, int userId) {
8991        ContentProviderRecord cpr;
8992        ContentProviderConnection conn = null;
8993        ProviderInfo cpi = null;
8994
8995        synchronized(this) {
8996            long startTime = SystemClock.elapsedRealtime();
8997
8998            ProcessRecord r = null;
8999            if (caller != null) {
9000                r = getRecordForAppLocked(caller);
9001                if (r == null) {
9002                    throw new SecurityException(
9003                            "Unable to find app for caller " + caller
9004                          + " (pid=" + Binder.getCallingPid()
9005                          + ") when getting content provider " + name);
9006                }
9007            }
9008
9009            boolean checkCrossUser = true;
9010
9011            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9012
9013            // First check if this content provider has been published...
9014            cpr = mProviderMap.getProviderByName(name, userId);
9015            // If that didn't work, check if it exists for user 0 and then
9016            // verify that it's a singleton provider before using it.
9017            if (cpr == null && userId != UserHandle.USER_OWNER) {
9018                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9019                if (cpr != null) {
9020                    cpi = cpr.info;
9021                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9022                            cpi.name, cpi.flags)
9023                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9024                        userId = UserHandle.USER_OWNER;
9025                        checkCrossUser = false;
9026                    } else {
9027                        cpr = null;
9028                        cpi = null;
9029                    }
9030                }
9031            }
9032
9033            boolean providerRunning = cpr != null;
9034            if (providerRunning) {
9035                cpi = cpr.info;
9036                String msg;
9037                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9038                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9039                        != null) {
9040                    throw new SecurityException(msg);
9041                }
9042                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9043
9044                if (r != null && cpr.canRunHere(r)) {
9045                    // This provider has been published or is in the process
9046                    // of being published...  but it is also allowed to run
9047                    // in the caller's process, so don't make a connection
9048                    // and just let the caller instantiate its own instance.
9049                    ContentProviderHolder holder = cpr.newHolder(null);
9050                    // don't give caller the provider object, it needs
9051                    // to make its own.
9052                    holder.provider = null;
9053                    return holder;
9054                }
9055
9056                final long origId = Binder.clearCallingIdentity();
9057
9058                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9059
9060                // In this case the provider instance already exists, so we can
9061                // return it right away.
9062                conn = incProviderCountLocked(r, cpr, token, stable);
9063                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9064                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9065                        // If this is a perceptible app accessing the provider,
9066                        // make sure to count it as being accessed and thus
9067                        // back up on the LRU list.  This is good because
9068                        // content providers are often expensive to start.
9069                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9070                        updateLruProcessLocked(cpr.proc, false, null);
9071                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9072                    }
9073                }
9074
9075                if (cpr.proc != null) {
9076                    if (false) {
9077                        if (cpr.name.flattenToShortString().equals(
9078                                "com.android.providers.calendar/.CalendarProvider2")) {
9079                            Slog.v(TAG, "****************** KILLING "
9080                                + cpr.name.flattenToShortString());
9081                            Process.killProcess(cpr.proc.pid);
9082                        }
9083                    }
9084                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9085                    boolean success = updateOomAdjLocked(cpr.proc);
9086                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9087                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9088                    // NOTE: there is still a race here where a signal could be
9089                    // pending on the process even though we managed to update its
9090                    // adj level.  Not sure what to do about this, but at least
9091                    // the race is now smaller.
9092                    if (!success) {
9093                        // Uh oh...  it looks like the provider's process
9094                        // has been killed on us.  We need to wait for a new
9095                        // process to be started, and make sure its death
9096                        // doesn't kill our process.
9097                        Slog.i(TAG,
9098                                "Existing provider " + cpr.name.flattenToShortString()
9099                                + " is crashing; detaching " + r);
9100                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9101                        checkTime(startTime, "getContentProviderImpl: before appDied");
9102                        appDiedLocked(cpr.proc);
9103                        checkTime(startTime, "getContentProviderImpl: after appDied");
9104                        if (!lastRef) {
9105                            // This wasn't the last ref our process had on
9106                            // the provider...  we have now been killed, bail.
9107                            return null;
9108                        }
9109                        providerRunning = false;
9110                        conn = null;
9111                    }
9112                }
9113
9114                Binder.restoreCallingIdentity(origId);
9115            }
9116
9117            boolean singleton;
9118            if (!providerRunning) {
9119                try {
9120                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9121                    cpi = AppGlobals.getPackageManager().
9122                        resolveContentProvider(name,
9123                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9124                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9125                } catch (RemoteException ex) {
9126                }
9127                if (cpi == null) {
9128                    return null;
9129                }
9130                // If the provider is a singleton AND
9131                // (it's a call within the same user || the provider is a
9132                // privileged app)
9133                // Then allow connecting to the singleton provider
9134                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9135                        cpi.name, cpi.flags)
9136                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9137                if (singleton) {
9138                    userId = UserHandle.USER_OWNER;
9139                }
9140                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9141                checkTime(startTime, "getContentProviderImpl: got app info for user");
9142
9143                String msg;
9144                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9145                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9146                        != null) {
9147                    throw new SecurityException(msg);
9148                }
9149                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9150
9151                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9152                        && !cpi.processName.equals("system")) {
9153                    // If this content provider does not run in the system
9154                    // process, and the system is not yet ready to run other
9155                    // processes, then fail fast instead of hanging.
9156                    throw new IllegalArgumentException(
9157                            "Attempt to launch content provider before system ready");
9158                }
9159
9160                // Make sure that the user who owns this provider is started.  If not,
9161                // we don't want to allow it to run.
9162                if (mStartedUsers.get(userId) == null) {
9163                    Slog.w(TAG, "Unable to launch app "
9164                            + cpi.applicationInfo.packageName + "/"
9165                            + cpi.applicationInfo.uid + " for provider "
9166                            + name + ": user " + userId + " is stopped");
9167                    return null;
9168                }
9169
9170                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9171                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9172                cpr = mProviderMap.getProviderByClass(comp, userId);
9173                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9174                final boolean firstClass = cpr == null;
9175                if (firstClass) {
9176                    try {
9177                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9178                        ApplicationInfo ai =
9179                            AppGlobals.getPackageManager().
9180                                getApplicationInfo(
9181                                        cpi.applicationInfo.packageName,
9182                                        STOCK_PM_FLAGS, userId);
9183                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9184                        if (ai == null) {
9185                            Slog.w(TAG, "No package info for content provider "
9186                                    + cpi.name);
9187                            return null;
9188                        }
9189                        ai = getAppInfoForUser(ai, userId);
9190                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9191                    } catch (RemoteException ex) {
9192                        // pm is in same process, this will never happen.
9193                    }
9194                }
9195
9196                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9197
9198                if (r != null && cpr.canRunHere(r)) {
9199                    // If this is a multiprocess provider, then just return its
9200                    // info and allow the caller to instantiate it.  Only do
9201                    // this if the provider is the same user as the caller's
9202                    // process, or can run as root (so can be in any process).
9203                    return cpr.newHolder(null);
9204                }
9205
9206                if (DEBUG_PROVIDER) {
9207                    RuntimeException e = new RuntimeException("here");
9208                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9209                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9210                }
9211
9212                // This is single process, and our app is now connecting to it.
9213                // See if we are already in the process of launching this
9214                // provider.
9215                final int N = mLaunchingProviders.size();
9216                int i;
9217                for (i=0; i<N; i++) {
9218                    if (mLaunchingProviders.get(i) == cpr) {
9219                        break;
9220                    }
9221                }
9222
9223                // If the provider is not already being launched, then get it
9224                // started.
9225                if (i >= N) {
9226                    final long origId = Binder.clearCallingIdentity();
9227
9228                    try {
9229                        // Content provider is now in use, its package can't be stopped.
9230                        try {
9231                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9232                            AppGlobals.getPackageManager().setPackageStoppedState(
9233                                    cpr.appInfo.packageName, false, userId);
9234                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9235                        } catch (RemoteException e) {
9236                        } catch (IllegalArgumentException e) {
9237                            Slog.w(TAG, "Failed trying to unstop package "
9238                                    + cpr.appInfo.packageName + ": " + e);
9239                        }
9240
9241                        // Use existing process if already started
9242                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9243                        ProcessRecord proc = getProcessRecordLocked(
9244                                cpi.processName, cpr.appInfo.uid, false);
9245                        if (proc != null && proc.thread != null) {
9246                            if (DEBUG_PROVIDER) {
9247                                Slog.d(TAG, "Installing in existing process " + proc);
9248                            }
9249                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9250                            proc.pubProviders.put(cpi.name, cpr);
9251                            try {
9252                                proc.thread.scheduleInstallProvider(cpi);
9253                            } catch (RemoteException e) {
9254                            }
9255                        } else {
9256                            checkTime(startTime, "getContentProviderImpl: before start process");
9257                            proc = startProcessLocked(cpi.processName,
9258                                    cpr.appInfo, false, 0, "content provider",
9259                                    new ComponentName(cpi.applicationInfo.packageName,
9260                                            cpi.name), false, false, false);
9261                            checkTime(startTime, "getContentProviderImpl: after start process");
9262                            if (proc == null) {
9263                                Slog.w(TAG, "Unable to launch app "
9264                                        + cpi.applicationInfo.packageName + "/"
9265                                        + cpi.applicationInfo.uid + " for provider "
9266                                        + name + ": process is bad");
9267                                return null;
9268                            }
9269                        }
9270                        cpr.launchingApp = proc;
9271                        mLaunchingProviders.add(cpr);
9272                    } finally {
9273                        Binder.restoreCallingIdentity(origId);
9274                    }
9275                }
9276
9277                checkTime(startTime, "getContentProviderImpl: updating data structures");
9278
9279                // Make sure the provider is published (the same provider class
9280                // may be published under multiple names).
9281                if (firstClass) {
9282                    mProviderMap.putProviderByClass(comp, cpr);
9283                }
9284
9285                mProviderMap.putProviderByName(name, cpr);
9286                conn = incProviderCountLocked(r, cpr, token, stable);
9287                if (conn != null) {
9288                    conn.waiting = true;
9289                }
9290            }
9291            checkTime(startTime, "getContentProviderImpl: done!");
9292        }
9293
9294        // Wait for the provider to be published...
9295        synchronized (cpr) {
9296            while (cpr.provider == null) {
9297                if (cpr.launchingApp == null) {
9298                    Slog.w(TAG, "Unable to launch app "
9299                            + cpi.applicationInfo.packageName + "/"
9300                            + cpi.applicationInfo.uid + " for provider "
9301                            + name + ": launching app became null");
9302                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9303                            UserHandle.getUserId(cpi.applicationInfo.uid),
9304                            cpi.applicationInfo.packageName,
9305                            cpi.applicationInfo.uid, name);
9306                    return null;
9307                }
9308                try {
9309                    if (DEBUG_MU) {
9310                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9311                                + cpr.launchingApp);
9312                    }
9313                    if (conn != null) {
9314                        conn.waiting = true;
9315                    }
9316                    cpr.wait();
9317                } catch (InterruptedException ex) {
9318                } finally {
9319                    if (conn != null) {
9320                        conn.waiting = false;
9321                    }
9322                }
9323            }
9324        }
9325        return cpr != null ? cpr.newHolder(conn) : null;
9326    }
9327
9328    @Override
9329    public final ContentProviderHolder getContentProvider(
9330            IApplicationThread caller, String name, int userId, boolean stable) {
9331        enforceNotIsolatedCaller("getContentProvider");
9332        if (caller == null) {
9333            String msg = "null IApplicationThread when getting content provider "
9334                    + name;
9335            Slog.w(TAG, msg);
9336            throw new SecurityException(msg);
9337        }
9338        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9339        // with cross-user grant.
9340        return getContentProviderImpl(caller, name, null, stable, userId);
9341    }
9342
9343    public ContentProviderHolder getContentProviderExternal(
9344            String name, int userId, IBinder token) {
9345        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9346            "Do not have permission in call getContentProviderExternal()");
9347        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9348                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9349        return getContentProviderExternalUnchecked(name, token, userId);
9350    }
9351
9352    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9353            IBinder token, int userId) {
9354        return getContentProviderImpl(null, name, token, true, userId);
9355    }
9356
9357    /**
9358     * Drop a content provider from a ProcessRecord's bookkeeping
9359     */
9360    public void removeContentProvider(IBinder connection, boolean stable) {
9361        enforceNotIsolatedCaller("removeContentProvider");
9362        long ident = Binder.clearCallingIdentity();
9363        try {
9364            synchronized (this) {
9365                ContentProviderConnection conn;
9366                try {
9367                    conn = (ContentProviderConnection)connection;
9368                } catch (ClassCastException e) {
9369                    String msg ="removeContentProvider: " + connection
9370                            + " not a ContentProviderConnection";
9371                    Slog.w(TAG, msg);
9372                    throw new IllegalArgumentException(msg);
9373                }
9374                if (conn == null) {
9375                    throw new NullPointerException("connection is null");
9376                }
9377                if (decProviderCountLocked(conn, null, null, stable)) {
9378                    updateOomAdjLocked();
9379                }
9380            }
9381        } finally {
9382            Binder.restoreCallingIdentity(ident);
9383        }
9384    }
9385
9386    public void removeContentProviderExternal(String name, IBinder token) {
9387        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9388            "Do not have permission in call removeContentProviderExternal()");
9389        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9390    }
9391
9392    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9393        synchronized (this) {
9394            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9395            if(cpr == null) {
9396                //remove from mProvidersByClass
9397                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9398                return;
9399            }
9400
9401            //update content provider record entry info
9402            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9403            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9404            if (localCpr.hasExternalProcessHandles()) {
9405                if (localCpr.removeExternalProcessHandleLocked(token)) {
9406                    updateOomAdjLocked();
9407                } else {
9408                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9409                            + " with no external reference for token: "
9410                            + token + ".");
9411                }
9412            } else {
9413                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9414                        + " with no external references.");
9415            }
9416        }
9417    }
9418
9419    public final void publishContentProviders(IApplicationThread caller,
9420            List<ContentProviderHolder> providers) {
9421        if (providers == null) {
9422            return;
9423        }
9424
9425        enforceNotIsolatedCaller("publishContentProviders");
9426        synchronized (this) {
9427            final ProcessRecord r = getRecordForAppLocked(caller);
9428            if (DEBUG_MU)
9429                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9430            if (r == null) {
9431                throw new SecurityException(
9432                        "Unable to find app for caller " + caller
9433                      + " (pid=" + Binder.getCallingPid()
9434                      + ") when publishing content providers");
9435            }
9436
9437            final long origId = Binder.clearCallingIdentity();
9438
9439            final int N = providers.size();
9440            for (int i=0; i<N; i++) {
9441                ContentProviderHolder src = providers.get(i);
9442                if (src == null || src.info == null || src.provider == null) {
9443                    continue;
9444                }
9445                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9446                if (DEBUG_MU)
9447                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9448                if (dst != null) {
9449                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9450                    mProviderMap.putProviderByClass(comp, dst);
9451                    String names[] = dst.info.authority.split(";");
9452                    for (int j = 0; j < names.length; j++) {
9453                        mProviderMap.putProviderByName(names[j], dst);
9454                    }
9455
9456                    int NL = mLaunchingProviders.size();
9457                    int j;
9458                    for (j=0; j<NL; j++) {
9459                        if (mLaunchingProviders.get(j) == dst) {
9460                            mLaunchingProviders.remove(j);
9461                            j--;
9462                            NL--;
9463                        }
9464                    }
9465                    synchronized (dst) {
9466                        dst.provider = src.provider;
9467                        dst.proc = r;
9468                        dst.notifyAll();
9469                    }
9470                    updateOomAdjLocked(r);
9471                }
9472            }
9473
9474            Binder.restoreCallingIdentity(origId);
9475        }
9476    }
9477
9478    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9479        ContentProviderConnection conn;
9480        try {
9481            conn = (ContentProviderConnection)connection;
9482        } catch (ClassCastException e) {
9483            String msg ="refContentProvider: " + connection
9484                    + " not a ContentProviderConnection";
9485            Slog.w(TAG, msg);
9486            throw new IllegalArgumentException(msg);
9487        }
9488        if (conn == null) {
9489            throw new NullPointerException("connection is null");
9490        }
9491
9492        synchronized (this) {
9493            if (stable > 0) {
9494                conn.numStableIncs += stable;
9495            }
9496            stable = conn.stableCount + stable;
9497            if (stable < 0) {
9498                throw new IllegalStateException("stableCount < 0: " + stable);
9499            }
9500
9501            if (unstable > 0) {
9502                conn.numUnstableIncs += unstable;
9503            }
9504            unstable = conn.unstableCount + unstable;
9505            if (unstable < 0) {
9506                throw new IllegalStateException("unstableCount < 0: " + unstable);
9507            }
9508
9509            if ((stable+unstable) <= 0) {
9510                throw new IllegalStateException("ref counts can't go to zero here: stable="
9511                        + stable + " unstable=" + unstable);
9512            }
9513            conn.stableCount = stable;
9514            conn.unstableCount = unstable;
9515            return !conn.dead;
9516        }
9517    }
9518
9519    public void unstableProviderDied(IBinder connection) {
9520        ContentProviderConnection conn;
9521        try {
9522            conn = (ContentProviderConnection)connection;
9523        } catch (ClassCastException e) {
9524            String msg ="refContentProvider: " + connection
9525                    + " not a ContentProviderConnection";
9526            Slog.w(TAG, msg);
9527            throw new IllegalArgumentException(msg);
9528        }
9529        if (conn == null) {
9530            throw new NullPointerException("connection is null");
9531        }
9532
9533        // Safely retrieve the content provider associated with the connection.
9534        IContentProvider provider;
9535        synchronized (this) {
9536            provider = conn.provider.provider;
9537        }
9538
9539        if (provider == null) {
9540            // Um, yeah, we're way ahead of you.
9541            return;
9542        }
9543
9544        // Make sure the caller is being honest with us.
9545        if (provider.asBinder().pingBinder()) {
9546            // Er, no, still looks good to us.
9547            synchronized (this) {
9548                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9549                        + " says " + conn + " died, but we don't agree");
9550                return;
9551            }
9552        }
9553
9554        // Well look at that!  It's dead!
9555        synchronized (this) {
9556            if (conn.provider.provider != provider) {
9557                // But something changed...  good enough.
9558                return;
9559            }
9560
9561            ProcessRecord proc = conn.provider.proc;
9562            if (proc == null || proc.thread == null) {
9563                // Seems like the process is already cleaned up.
9564                return;
9565            }
9566
9567            // As far as we're concerned, this is just like receiving a
9568            // death notification...  just a bit prematurely.
9569            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9570                    + ") early provider death");
9571            final long ident = Binder.clearCallingIdentity();
9572            try {
9573                appDiedLocked(proc);
9574            } finally {
9575                Binder.restoreCallingIdentity(ident);
9576            }
9577        }
9578    }
9579
9580    @Override
9581    public void appNotRespondingViaProvider(IBinder connection) {
9582        enforceCallingPermission(
9583                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9584
9585        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9586        if (conn == null) {
9587            Slog.w(TAG, "ContentProviderConnection is null");
9588            return;
9589        }
9590
9591        final ProcessRecord host = conn.provider.proc;
9592        if (host == null) {
9593            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9594            return;
9595        }
9596
9597        final long token = Binder.clearCallingIdentity();
9598        try {
9599            appNotResponding(host, null, null, false, "ContentProvider not responding");
9600        } finally {
9601            Binder.restoreCallingIdentity(token);
9602        }
9603    }
9604
9605    public final void installSystemProviders() {
9606        List<ProviderInfo> providers;
9607        synchronized (this) {
9608            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9609            providers = generateApplicationProvidersLocked(app);
9610            if (providers != null) {
9611                for (int i=providers.size()-1; i>=0; i--) {
9612                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9613                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9614                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9615                                + ": not system .apk");
9616                        providers.remove(i);
9617                    }
9618                }
9619            }
9620        }
9621        if (providers != null) {
9622            mSystemThread.installSystemProviders(providers);
9623        }
9624
9625        mCoreSettingsObserver = new CoreSettingsObserver(this);
9626
9627        //mUsageStatsService.monitorPackages();
9628    }
9629
9630    /**
9631     * Allows apps to retrieve the MIME type of a URI.
9632     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9633     * users, then it does not need permission to access the ContentProvider.
9634     * Either, it needs cross-user uri grants.
9635     *
9636     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9637     *
9638     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9639     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9640     */
9641    public String getProviderMimeType(Uri uri, int userId) {
9642        enforceNotIsolatedCaller("getProviderMimeType");
9643        final String name = uri.getAuthority();
9644        int callingUid = Binder.getCallingUid();
9645        int callingPid = Binder.getCallingPid();
9646        long ident = 0;
9647        boolean clearedIdentity = false;
9648        userId = unsafeConvertIncomingUser(userId);
9649        if (UserHandle.getUserId(callingUid) != userId) {
9650            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9651                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9652                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9653                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9654                clearedIdentity = true;
9655                ident = Binder.clearCallingIdentity();
9656            }
9657        }
9658        ContentProviderHolder holder = null;
9659        try {
9660            holder = getContentProviderExternalUnchecked(name, null, userId);
9661            if (holder != null) {
9662                return holder.provider.getType(uri);
9663            }
9664        } catch (RemoteException e) {
9665            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9666            return null;
9667        } finally {
9668            // We need to clear the identity to call removeContentProviderExternalUnchecked
9669            if (!clearedIdentity) {
9670                ident = Binder.clearCallingIdentity();
9671            }
9672            try {
9673                if (holder != null) {
9674                    removeContentProviderExternalUnchecked(name, null, userId);
9675                }
9676            } finally {
9677                Binder.restoreCallingIdentity(ident);
9678            }
9679        }
9680
9681        return null;
9682    }
9683
9684    // =========================================================
9685    // GLOBAL MANAGEMENT
9686    // =========================================================
9687
9688    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9689            boolean isolated, int isolatedUid) {
9690        String proc = customProcess != null ? customProcess : info.processName;
9691        BatteryStatsImpl.Uid.Proc ps = null;
9692        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9693        int uid = info.uid;
9694        if (isolated) {
9695            if (isolatedUid == 0) {
9696                int userId = UserHandle.getUserId(uid);
9697                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9698                while (true) {
9699                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9700                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9701                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9702                    }
9703                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9704                    mNextIsolatedProcessUid++;
9705                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9706                        // No process for this uid, use it.
9707                        break;
9708                    }
9709                    stepsLeft--;
9710                    if (stepsLeft <= 0) {
9711                        return null;
9712                    }
9713                }
9714            } else {
9715                // Special case for startIsolatedProcess (internal only), where
9716                // the uid of the isolated process is specified by the caller.
9717                uid = isolatedUid;
9718            }
9719        }
9720        return new ProcessRecord(stats, info, proc, uid);
9721    }
9722
9723    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9724            String abiOverride) {
9725        ProcessRecord app;
9726        if (!isolated) {
9727            app = getProcessRecordLocked(info.processName, info.uid, true);
9728        } else {
9729            app = null;
9730        }
9731
9732        if (app == null) {
9733            app = newProcessRecordLocked(info, null, isolated, 0);
9734            mProcessNames.put(info.processName, app.uid, app);
9735            if (isolated) {
9736                mIsolatedProcesses.put(app.uid, app);
9737            }
9738            updateLruProcessLocked(app, false, null);
9739            updateOomAdjLocked();
9740        }
9741
9742        // This package really, really can not be stopped.
9743        try {
9744            AppGlobals.getPackageManager().setPackageStoppedState(
9745                    info.packageName, false, UserHandle.getUserId(app.uid));
9746        } catch (RemoteException e) {
9747        } catch (IllegalArgumentException e) {
9748            Slog.w(TAG, "Failed trying to unstop package "
9749                    + info.packageName + ": " + e);
9750        }
9751
9752        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9753                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9754            app.persistent = true;
9755            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9756        }
9757        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9758            mPersistentStartingProcesses.add(app);
9759            startProcessLocked(app, "added application", app.processName, abiOverride,
9760                    null /* entryPoint */, null /* entryPointArgs */);
9761        }
9762
9763        return app;
9764    }
9765
9766    public void unhandledBack() {
9767        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9768                "unhandledBack()");
9769
9770        synchronized(this) {
9771            final long origId = Binder.clearCallingIdentity();
9772            try {
9773                getFocusedStack().unhandledBackLocked();
9774            } finally {
9775                Binder.restoreCallingIdentity(origId);
9776            }
9777        }
9778    }
9779
9780    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9781        enforceNotIsolatedCaller("openContentUri");
9782        final int userId = UserHandle.getCallingUserId();
9783        String name = uri.getAuthority();
9784        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9785        ParcelFileDescriptor pfd = null;
9786        if (cph != null) {
9787            // We record the binder invoker's uid in thread-local storage before
9788            // going to the content provider to open the file.  Later, in the code
9789            // that handles all permissions checks, we look for this uid and use
9790            // that rather than the Activity Manager's own uid.  The effect is that
9791            // we do the check against the caller's permissions even though it looks
9792            // to the content provider like the Activity Manager itself is making
9793            // the request.
9794            sCallerIdentity.set(new Identity(
9795                    Binder.getCallingPid(), Binder.getCallingUid()));
9796            try {
9797                pfd = cph.provider.openFile(null, uri, "r", null);
9798            } catch (FileNotFoundException e) {
9799                // do nothing; pfd will be returned null
9800            } finally {
9801                // Ensure that whatever happens, we clean up the identity state
9802                sCallerIdentity.remove();
9803            }
9804
9805            // We've got the fd now, so we're done with the provider.
9806            removeContentProviderExternalUnchecked(name, null, userId);
9807        } else {
9808            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9809        }
9810        return pfd;
9811    }
9812
9813    // Actually is sleeping or shutting down or whatever else in the future
9814    // is an inactive state.
9815    public boolean isSleepingOrShuttingDown() {
9816        return mSleeping || mShuttingDown;
9817    }
9818
9819    public boolean isSleeping() {
9820        return mSleeping;
9821    }
9822
9823    void goingToSleep() {
9824        synchronized(this) {
9825            mWentToSleep = true;
9826            updateEventDispatchingLocked();
9827            goToSleepIfNeededLocked();
9828        }
9829    }
9830
9831    void finishRunningVoiceLocked() {
9832        if (mRunningVoice) {
9833            mRunningVoice = false;
9834            goToSleepIfNeededLocked();
9835        }
9836    }
9837
9838    void goToSleepIfNeededLocked() {
9839        if (mWentToSleep && !mRunningVoice) {
9840            if (!mSleeping) {
9841                mSleeping = true;
9842                mStackSupervisor.goingToSleepLocked();
9843
9844                // Initialize the wake times of all processes.
9845                checkExcessivePowerUsageLocked(false);
9846                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9847                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9848                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9849            }
9850        }
9851    }
9852
9853    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9854        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9855            // Never persist the home stack.
9856            return;
9857        }
9858        mTaskPersister.wakeup(task, flush);
9859    }
9860
9861    @Override
9862    public boolean shutdown(int timeout) {
9863        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9864                != PackageManager.PERMISSION_GRANTED) {
9865            throw new SecurityException("Requires permission "
9866                    + android.Manifest.permission.SHUTDOWN);
9867        }
9868
9869        boolean timedout = false;
9870
9871        synchronized(this) {
9872            mShuttingDown = true;
9873            updateEventDispatchingLocked();
9874            timedout = mStackSupervisor.shutdownLocked(timeout);
9875        }
9876
9877        mAppOpsService.shutdown();
9878        if (mUsageStatsService != null) {
9879            mUsageStatsService.prepareShutdown();
9880        }
9881        mBatteryStatsService.shutdown();
9882        synchronized (this) {
9883            mProcessStats.shutdownLocked();
9884        }
9885        notifyTaskPersisterLocked(null, true);
9886
9887        return timedout;
9888    }
9889
9890    public final void activitySlept(IBinder token) {
9891        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9892
9893        final long origId = Binder.clearCallingIdentity();
9894
9895        synchronized (this) {
9896            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9897            if (r != null) {
9898                mStackSupervisor.activitySleptLocked(r);
9899            }
9900        }
9901
9902        Binder.restoreCallingIdentity(origId);
9903    }
9904
9905    void logLockScreen(String msg) {
9906        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9907                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9908                mWentToSleep + " mSleeping=" + mSleeping);
9909    }
9910
9911    private void comeOutOfSleepIfNeededLocked() {
9912        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9913            if (mSleeping) {
9914                mSleeping = false;
9915                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9916            }
9917        }
9918    }
9919
9920    void wakingUp() {
9921        synchronized(this) {
9922            mWentToSleep = false;
9923            updateEventDispatchingLocked();
9924            comeOutOfSleepIfNeededLocked();
9925        }
9926    }
9927
9928    void startRunningVoiceLocked() {
9929        if (!mRunningVoice) {
9930            mRunningVoice = true;
9931            comeOutOfSleepIfNeededLocked();
9932        }
9933    }
9934
9935    private void updateEventDispatchingLocked() {
9936        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9937    }
9938
9939    public void setLockScreenShown(boolean shown) {
9940        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9941                != PackageManager.PERMISSION_GRANTED) {
9942            throw new SecurityException("Requires permission "
9943                    + android.Manifest.permission.DEVICE_POWER);
9944        }
9945
9946        synchronized(this) {
9947            long ident = Binder.clearCallingIdentity();
9948            try {
9949                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9950                mLockScreenShown = shown;
9951                comeOutOfSleepIfNeededLocked();
9952            } finally {
9953                Binder.restoreCallingIdentity(ident);
9954            }
9955        }
9956    }
9957
9958    @Override
9959    public void stopAppSwitches() {
9960        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9961                != PackageManager.PERMISSION_GRANTED) {
9962            throw new SecurityException("Requires permission "
9963                    + android.Manifest.permission.STOP_APP_SWITCHES);
9964        }
9965
9966        synchronized(this) {
9967            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9968                    + APP_SWITCH_DELAY_TIME;
9969            mDidAppSwitch = false;
9970            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9971            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9972            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9973        }
9974    }
9975
9976    public void resumeAppSwitches() {
9977        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9978                != PackageManager.PERMISSION_GRANTED) {
9979            throw new SecurityException("Requires permission "
9980                    + android.Manifest.permission.STOP_APP_SWITCHES);
9981        }
9982
9983        synchronized(this) {
9984            // Note that we don't execute any pending app switches... we will
9985            // let those wait until either the timeout, or the next start
9986            // activity request.
9987            mAppSwitchesAllowedTime = 0;
9988        }
9989    }
9990
9991    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9992            String name) {
9993        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9994            return true;
9995        }
9996
9997        final int perm = checkComponentPermission(
9998                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9999                callingUid, -1, true);
10000        if (perm == PackageManager.PERMISSION_GRANTED) {
10001            return true;
10002        }
10003
10004        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10005        return false;
10006    }
10007
10008    public void setDebugApp(String packageName, boolean waitForDebugger,
10009            boolean persistent) {
10010        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10011                "setDebugApp()");
10012
10013        long ident = Binder.clearCallingIdentity();
10014        try {
10015            // Note that this is not really thread safe if there are multiple
10016            // callers into it at the same time, but that's not a situation we
10017            // care about.
10018            if (persistent) {
10019                final ContentResolver resolver = mContext.getContentResolver();
10020                Settings.Global.putString(
10021                    resolver, Settings.Global.DEBUG_APP,
10022                    packageName);
10023                Settings.Global.putInt(
10024                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10025                    waitForDebugger ? 1 : 0);
10026            }
10027
10028            synchronized (this) {
10029                if (!persistent) {
10030                    mOrigDebugApp = mDebugApp;
10031                    mOrigWaitForDebugger = mWaitForDebugger;
10032                }
10033                mDebugApp = packageName;
10034                mWaitForDebugger = waitForDebugger;
10035                mDebugTransient = !persistent;
10036                if (packageName != null) {
10037                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10038                            false, UserHandle.USER_ALL, "set debug app");
10039                }
10040            }
10041        } finally {
10042            Binder.restoreCallingIdentity(ident);
10043        }
10044    }
10045
10046    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10047        synchronized (this) {
10048            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10049            if (!isDebuggable) {
10050                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10051                    throw new SecurityException("Process not debuggable: " + app.packageName);
10052                }
10053            }
10054
10055            mOpenGlTraceApp = processName;
10056        }
10057    }
10058
10059    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10060        synchronized (this) {
10061            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10062            if (!isDebuggable) {
10063                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10064                    throw new SecurityException("Process not debuggable: " + app.packageName);
10065                }
10066            }
10067            mProfileApp = processName;
10068            mProfileFile = profilerInfo.profileFile;
10069            if (mProfileFd != null) {
10070                try {
10071                    mProfileFd.close();
10072                } catch (IOException e) {
10073                }
10074                mProfileFd = null;
10075            }
10076            mProfileFd = profilerInfo.profileFd;
10077            mSamplingInterval = profilerInfo.samplingInterval;
10078            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10079            mProfileType = 0;
10080        }
10081    }
10082
10083    @Override
10084    public void setAlwaysFinish(boolean enabled) {
10085        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10086                "setAlwaysFinish()");
10087
10088        Settings.Global.putInt(
10089                mContext.getContentResolver(),
10090                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10091
10092        synchronized (this) {
10093            mAlwaysFinishActivities = enabled;
10094        }
10095    }
10096
10097    @Override
10098    public void setActivityController(IActivityController controller) {
10099        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10100                "setActivityController()");
10101        synchronized (this) {
10102            mController = controller;
10103            Watchdog.getInstance().setActivityController(controller);
10104        }
10105    }
10106
10107    @Override
10108    public void setUserIsMonkey(boolean userIsMonkey) {
10109        synchronized (this) {
10110            synchronized (mPidsSelfLocked) {
10111                final int callingPid = Binder.getCallingPid();
10112                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10113                if (precessRecord == null) {
10114                    throw new SecurityException("Unknown process: " + callingPid);
10115                }
10116                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10117                    throw new SecurityException("Only an instrumentation process "
10118                            + "with a UiAutomation can call setUserIsMonkey");
10119                }
10120            }
10121            mUserIsMonkey = userIsMonkey;
10122        }
10123    }
10124
10125    @Override
10126    public boolean isUserAMonkey() {
10127        synchronized (this) {
10128            // If there is a controller also implies the user is a monkey.
10129            return (mUserIsMonkey || mController != null);
10130        }
10131    }
10132
10133    public void requestBugReport() {
10134        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10135        SystemProperties.set("ctl.start", "bugreport");
10136    }
10137
10138    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10139        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10140    }
10141
10142    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10143        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10144            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10145        }
10146        return KEY_DISPATCHING_TIMEOUT;
10147    }
10148
10149    @Override
10150    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10151        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10152                != PackageManager.PERMISSION_GRANTED) {
10153            throw new SecurityException("Requires permission "
10154                    + android.Manifest.permission.FILTER_EVENTS);
10155        }
10156        ProcessRecord proc;
10157        long timeout;
10158        synchronized (this) {
10159            synchronized (mPidsSelfLocked) {
10160                proc = mPidsSelfLocked.get(pid);
10161            }
10162            timeout = getInputDispatchingTimeoutLocked(proc);
10163        }
10164
10165        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10166            return -1;
10167        }
10168
10169        return timeout;
10170    }
10171
10172    /**
10173     * Handle input dispatching timeouts.
10174     * Returns whether input dispatching should be aborted or not.
10175     */
10176    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10177            final ActivityRecord activity, final ActivityRecord parent,
10178            final boolean aboveSystem, String reason) {
10179        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10180                != PackageManager.PERMISSION_GRANTED) {
10181            throw new SecurityException("Requires permission "
10182                    + android.Manifest.permission.FILTER_EVENTS);
10183        }
10184
10185        final String annotation;
10186        if (reason == null) {
10187            annotation = "Input dispatching timed out";
10188        } else {
10189            annotation = "Input dispatching timed out (" + reason + ")";
10190        }
10191
10192        if (proc != null) {
10193            synchronized (this) {
10194                if (proc.debugging) {
10195                    return false;
10196                }
10197
10198                if (mDidDexOpt) {
10199                    // Give more time since we were dexopting.
10200                    mDidDexOpt = false;
10201                    return false;
10202                }
10203
10204                if (proc.instrumentationClass != null) {
10205                    Bundle info = new Bundle();
10206                    info.putString("shortMsg", "keyDispatchingTimedOut");
10207                    info.putString("longMsg", annotation);
10208                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10209                    return true;
10210                }
10211            }
10212            mHandler.post(new Runnable() {
10213                @Override
10214                public void run() {
10215                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10216                }
10217            });
10218        }
10219
10220        return true;
10221    }
10222
10223    public Bundle getAssistContextExtras(int requestType) {
10224        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10225                "getAssistContextExtras()");
10226        PendingAssistExtras pae;
10227        Bundle extras = new Bundle();
10228        synchronized (this) {
10229            ActivityRecord activity = getFocusedStack().mResumedActivity;
10230            if (activity == null) {
10231                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10232                return null;
10233            }
10234            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10235            if (activity.app == null || activity.app.thread == null) {
10236                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10237                return extras;
10238            }
10239            if (activity.app.pid == Binder.getCallingPid()) {
10240                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10241                return extras;
10242            }
10243            pae = new PendingAssistExtras(activity);
10244            try {
10245                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10246                        requestType);
10247                mPendingAssistExtras.add(pae);
10248                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10249            } catch (RemoteException e) {
10250                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10251                return extras;
10252            }
10253        }
10254        synchronized (pae) {
10255            while (!pae.haveResult) {
10256                try {
10257                    pae.wait();
10258                } catch (InterruptedException e) {
10259                }
10260            }
10261            if (pae.result != null) {
10262                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10263            }
10264        }
10265        synchronized (this) {
10266            mPendingAssistExtras.remove(pae);
10267            mHandler.removeCallbacks(pae);
10268        }
10269        return extras;
10270    }
10271
10272    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10273        PendingAssistExtras pae = (PendingAssistExtras)token;
10274        synchronized (pae) {
10275            pae.result = extras;
10276            pae.haveResult = true;
10277            pae.notifyAll();
10278        }
10279    }
10280
10281    public void registerProcessObserver(IProcessObserver observer) {
10282        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10283                "registerProcessObserver()");
10284        synchronized (this) {
10285            mProcessObservers.register(observer);
10286        }
10287    }
10288
10289    @Override
10290    public void unregisterProcessObserver(IProcessObserver observer) {
10291        synchronized (this) {
10292            mProcessObservers.unregister(observer);
10293        }
10294    }
10295
10296    @Override
10297    public boolean convertFromTranslucent(IBinder token) {
10298        final long origId = Binder.clearCallingIdentity();
10299        try {
10300            synchronized (this) {
10301                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10302                if (r == null) {
10303                    return false;
10304                }
10305                final boolean translucentChanged = r.changeWindowTranslucency(true);
10306                if (translucentChanged) {
10307                    r.task.stack.releaseBackgroundResources();
10308                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10309                }
10310                mWindowManager.setAppFullscreen(token, true);
10311                return translucentChanged;
10312            }
10313        } finally {
10314            Binder.restoreCallingIdentity(origId);
10315        }
10316    }
10317
10318    @Override
10319    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10320        final long origId = Binder.clearCallingIdentity();
10321        try {
10322            synchronized (this) {
10323                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10324                if (r == null) {
10325                    return false;
10326                }
10327                int index = r.task.mActivities.lastIndexOf(r);
10328                if (index > 0) {
10329                    ActivityRecord under = r.task.mActivities.get(index - 1);
10330                    under.returningOptions = options;
10331                }
10332                final boolean translucentChanged = r.changeWindowTranslucency(false);
10333                if (translucentChanged) {
10334                    r.task.stack.convertToTranslucent(r);
10335                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10336                }
10337                mWindowManager.setAppFullscreen(token, false);
10338                return translucentChanged;
10339            }
10340        } finally {
10341            Binder.restoreCallingIdentity(origId);
10342        }
10343    }
10344
10345    @Override
10346    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10347        final long origId = Binder.clearCallingIdentity();
10348        try {
10349            synchronized (this) {
10350                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10351                if (r != null) {
10352                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10353                }
10354            }
10355            return false;
10356        } finally {
10357            Binder.restoreCallingIdentity(origId);
10358        }
10359    }
10360
10361    @Override
10362    public boolean isBackgroundVisibleBehind(IBinder token) {
10363        final long origId = Binder.clearCallingIdentity();
10364        try {
10365            synchronized (this) {
10366                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10367                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10368                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10369                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10370                return visible;
10371            }
10372        } finally {
10373            Binder.restoreCallingIdentity(origId);
10374        }
10375    }
10376
10377    @Override
10378    public ActivityOptions getActivityOptions(IBinder token) {
10379        final long origId = Binder.clearCallingIdentity();
10380        try {
10381            synchronized (this) {
10382                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10383                if (r != null) {
10384                    final ActivityOptions activityOptions = r.pendingOptions;
10385                    r.pendingOptions = null;
10386                    return activityOptions;
10387                }
10388                return null;
10389            }
10390        } finally {
10391            Binder.restoreCallingIdentity(origId);
10392        }
10393    }
10394
10395    @Override
10396    public void setImmersive(IBinder token, boolean immersive) {
10397        synchronized(this) {
10398            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10399            if (r == null) {
10400                throw new IllegalArgumentException();
10401            }
10402            r.immersive = immersive;
10403
10404            // update associated state if we're frontmost
10405            if (r == mFocusedActivity) {
10406                if (DEBUG_IMMERSIVE) {
10407                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10408                }
10409                applyUpdateLockStateLocked(r);
10410            }
10411        }
10412    }
10413
10414    @Override
10415    public boolean isImmersive(IBinder token) {
10416        synchronized (this) {
10417            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10418            if (r == null) {
10419                throw new IllegalArgumentException();
10420            }
10421            return r.immersive;
10422        }
10423    }
10424
10425    public boolean isTopActivityImmersive() {
10426        enforceNotIsolatedCaller("startActivity");
10427        synchronized (this) {
10428            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10429            return (r != null) ? r.immersive : false;
10430        }
10431    }
10432
10433    @Override
10434    public boolean isTopOfTask(IBinder token) {
10435        synchronized (this) {
10436            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10437            if (r == null) {
10438                throw new IllegalArgumentException();
10439            }
10440            return r.task.getTopActivity() == r;
10441        }
10442    }
10443
10444    public final void enterSafeMode() {
10445        synchronized(this) {
10446            // It only makes sense to do this before the system is ready
10447            // and started launching other packages.
10448            if (!mSystemReady) {
10449                try {
10450                    AppGlobals.getPackageManager().enterSafeMode();
10451                } catch (RemoteException e) {
10452                }
10453            }
10454
10455            mSafeMode = true;
10456        }
10457    }
10458
10459    public final void showSafeModeOverlay() {
10460        View v = LayoutInflater.from(mContext).inflate(
10461                com.android.internal.R.layout.safe_mode, null);
10462        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10463        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10464        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10465        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10466        lp.gravity = Gravity.BOTTOM | Gravity.START;
10467        lp.format = v.getBackground().getOpacity();
10468        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10469                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10470        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10471        ((WindowManager)mContext.getSystemService(
10472                Context.WINDOW_SERVICE)).addView(v, lp);
10473    }
10474
10475    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10476        if (!(sender instanceof PendingIntentRecord)) {
10477            return;
10478        }
10479        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10480        synchronized (stats) {
10481            if (mBatteryStatsService.isOnBattery()) {
10482                mBatteryStatsService.enforceCallingPermission();
10483                PendingIntentRecord rec = (PendingIntentRecord)sender;
10484                int MY_UID = Binder.getCallingUid();
10485                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10486                BatteryStatsImpl.Uid.Pkg pkg =
10487                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10488                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10489                pkg.incWakeupsLocked();
10490            }
10491        }
10492    }
10493
10494    public boolean killPids(int[] pids, String pReason, boolean secure) {
10495        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10496            throw new SecurityException("killPids only available to the system");
10497        }
10498        String reason = (pReason == null) ? "Unknown" : pReason;
10499        // XXX Note: don't acquire main activity lock here, because the window
10500        // manager calls in with its locks held.
10501
10502        boolean killed = false;
10503        synchronized (mPidsSelfLocked) {
10504            int[] types = new int[pids.length];
10505            int worstType = 0;
10506            for (int i=0; i<pids.length; i++) {
10507                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10508                if (proc != null) {
10509                    int type = proc.setAdj;
10510                    types[i] = type;
10511                    if (type > worstType) {
10512                        worstType = type;
10513                    }
10514                }
10515            }
10516
10517            // If the worst oom_adj is somewhere in the cached proc LRU range,
10518            // then constrain it so we will kill all cached procs.
10519            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10520                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10521                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10522            }
10523
10524            // If this is not a secure call, don't let it kill processes that
10525            // are important.
10526            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10527                worstType = ProcessList.SERVICE_ADJ;
10528            }
10529
10530            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10531            for (int i=0; i<pids.length; i++) {
10532                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10533                if (proc == null) {
10534                    continue;
10535                }
10536                int adj = proc.setAdj;
10537                if (adj >= worstType && !proc.killedByAm) {
10538                    proc.kill(reason, true);
10539                    killed = true;
10540                }
10541            }
10542        }
10543        return killed;
10544    }
10545
10546    @Override
10547    public void killUid(int uid, String reason) {
10548        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10549            throw new SecurityException("killUid only available to the system");
10550        }
10551        synchronized (this) {
10552            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10553                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10554                    reason != null ? reason : "kill uid");
10555        }
10556    }
10557
10558    @Override
10559    public boolean killProcessesBelowForeground(String reason) {
10560        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10561            throw new SecurityException("killProcessesBelowForeground() only available to system");
10562        }
10563
10564        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10565    }
10566
10567    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10568        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10569            throw new SecurityException("killProcessesBelowAdj() only available to system");
10570        }
10571
10572        boolean killed = false;
10573        synchronized (mPidsSelfLocked) {
10574            final int size = mPidsSelfLocked.size();
10575            for (int i = 0; i < size; i++) {
10576                final int pid = mPidsSelfLocked.keyAt(i);
10577                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10578                if (proc == null) continue;
10579
10580                final int adj = proc.setAdj;
10581                if (adj > belowAdj && !proc.killedByAm) {
10582                    proc.kill(reason, true);
10583                    killed = true;
10584                }
10585            }
10586        }
10587        return killed;
10588    }
10589
10590    @Override
10591    public void hang(final IBinder who, boolean allowRestart) {
10592        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10593                != PackageManager.PERMISSION_GRANTED) {
10594            throw new SecurityException("Requires permission "
10595                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10596        }
10597
10598        final IBinder.DeathRecipient death = new DeathRecipient() {
10599            @Override
10600            public void binderDied() {
10601                synchronized (this) {
10602                    notifyAll();
10603                }
10604            }
10605        };
10606
10607        try {
10608            who.linkToDeath(death, 0);
10609        } catch (RemoteException e) {
10610            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10611            return;
10612        }
10613
10614        synchronized (this) {
10615            Watchdog.getInstance().setAllowRestart(allowRestart);
10616            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10617            synchronized (death) {
10618                while (who.isBinderAlive()) {
10619                    try {
10620                        death.wait();
10621                    } catch (InterruptedException e) {
10622                    }
10623                }
10624            }
10625            Watchdog.getInstance().setAllowRestart(true);
10626        }
10627    }
10628
10629    @Override
10630    public void restart() {
10631        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10632                != PackageManager.PERMISSION_GRANTED) {
10633            throw new SecurityException("Requires permission "
10634                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10635        }
10636
10637        Log.i(TAG, "Sending shutdown broadcast...");
10638
10639        BroadcastReceiver br = new BroadcastReceiver() {
10640            @Override public void onReceive(Context context, Intent intent) {
10641                // Now the broadcast is done, finish up the low-level shutdown.
10642                Log.i(TAG, "Shutting down activity manager...");
10643                shutdown(10000);
10644                Log.i(TAG, "Shutdown complete, restarting!");
10645                Process.killProcess(Process.myPid());
10646                System.exit(10);
10647            }
10648        };
10649
10650        // First send the high-level shut down broadcast.
10651        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10652        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10653        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10654        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10655        mContext.sendOrderedBroadcastAsUser(intent,
10656                UserHandle.ALL, null, br, mHandler, 0, null, null);
10657        */
10658        br.onReceive(mContext, intent);
10659    }
10660
10661    private long getLowRamTimeSinceIdle(long now) {
10662        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10663    }
10664
10665    @Override
10666    public void performIdleMaintenance() {
10667        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10668                != PackageManager.PERMISSION_GRANTED) {
10669            throw new SecurityException("Requires permission "
10670                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10671        }
10672
10673        synchronized (this) {
10674            final long now = SystemClock.uptimeMillis();
10675            final long timeSinceLastIdle = now - mLastIdleTime;
10676            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10677            mLastIdleTime = now;
10678            mLowRamTimeSinceLastIdle = 0;
10679            if (mLowRamStartTime != 0) {
10680                mLowRamStartTime = now;
10681            }
10682
10683            StringBuilder sb = new StringBuilder(128);
10684            sb.append("Idle maintenance over ");
10685            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10686            sb.append(" low RAM for ");
10687            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10688            Slog.i(TAG, sb.toString());
10689
10690            // If at least 1/3 of our time since the last idle period has been spent
10691            // with RAM low, then we want to kill processes.
10692            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10693
10694            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10695                ProcessRecord proc = mLruProcesses.get(i);
10696                if (proc.notCachedSinceIdle) {
10697                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10698                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10699                        if (doKilling && proc.initialIdlePss != 0
10700                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10701                            proc.kill("idle maint (pss " + proc.lastPss
10702                                    + " from " + proc.initialIdlePss + ")", true);
10703                        }
10704                    }
10705                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10706                    proc.notCachedSinceIdle = true;
10707                    proc.initialIdlePss = 0;
10708                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10709                            isSleeping(), now);
10710                }
10711            }
10712
10713            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10714            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10715        }
10716    }
10717
10718    private void retrieveSettings() {
10719        final ContentResolver resolver = mContext.getContentResolver();
10720        String debugApp = Settings.Global.getString(
10721            resolver, Settings.Global.DEBUG_APP);
10722        boolean waitForDebugger = Settings.Global.getInt(
10723            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10724        boolean alwaysFinishActivities = Settings.Global.getInt(
10725            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10726        boolean forceRtl = Settings.Global.getInt(
10727                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10728        // Transfer any global setting for forcing RTL layout, into a System Property
10729        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10730
10731        Configuration configuration = new Configuration();
10732        Settings.System.getConfiguration(resolver, configuration);
10733        if (forceRtl) {
10734            // This will take care of setting the correct layout direction flags
10735            configuration.setLayoutDirection(configuration.locale);
10736        }
10737
10738        synchronized (this) {
10739            mDebugApp = mOrigDebugApp = debugApp;
10740            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10741            mAlwaysFinishActivities = alwaysFinishActivities;
10742            // This happens before any activities are started, so we can
10743            // change mConfiguration in-place.
10744            updateConfigurationLocked(configuration, null, false, true);
10745            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10746        }
10747    }
10748
10749    /** Loads resources after the current configuration has been set. */
10750    private void loadResourcesOnSystemReady() {
10751        final Resources res = mContext.getResources();
10752        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10753        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10754        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10755    }
10756
10757    public boolean testIsSystemReady() {
10758        // no need to synchronize(this) just to read & return the value
10759        return mSystemReady;
10760    }
10761
10762    private static File getCalledPreBootReceiversFile() {
10763        File dataDir = Environment.getDataDirectory();
10764        File systemDir = new File(dataDir, "system");
10765        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10766        return fname;
10767    }
10768
10769    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10770        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10771        File file = getCalledPreBootReceiversFile();
10772        FileInputStream fis = null;
10773        try {
10774            fis = new FileInputStream(file);
10775            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10776            int fvers = dis.readInt();
10777            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10778                String vers = dis.readUTF();
10779                String codename = dis.readUTF();
10780                String build = dis.readUTF();
10781                if (android.os.Build.VERSION.RELEASE.equals(vers)
10782                        && android.os.Build.VERSION.CODENAME.equals(codename)
10783                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10784                    int num = dis.readInt();
10785                    while (num > 0) {
10786                        num--;
10787                        String pkg = dis.readUTF();
10788                        String cls = dis.readUTF();
10789                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10790                    }
10791                }
10792            }
10793        } catch (FileNotFoundException e) {
10794        } catch (IOException e) {
10795            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10796        } finally {
10797            if (fis != null) {
10798                try {
10799                    fis.close();
10800                } catch (IOException e) {
10801                }
10802            }
10803        }
10804        return lastDoneReceivers;
10805    }
10806
10807    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10808        File file = getCalledPreBootReceiversFile();
10809        FileOutputStream fos = null;
10810        DataOutputStream dos = null;
10811        try {
10812            fos = new FileOutputStream(file);
10813            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10814            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10815            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10816            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10817            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10818            dos.writeInt(list.size());
10819            for (int i=0; i<list.size(); i++) {
10820                dos.writeUTF(list.get(i).getPackageName());
10821                dos.writeUTF(list.get(i).getClassName());
10822            }
10823        } catch (IOException e) {
10824            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10825            file.delete();
10826        } finally {
10827            FileUtils.sync(fos);
10828            if (dos != null) {
10829                try {
10830                    dos.close();
10831                } catch (IOException e) {
10832                    // TODO Auto-generated catch block
10833                    e.printStackTrace();
10834                }
10835            }
10836        }
10837    }
10838
10839    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10840            ArrayList<ComponentName> doneReceivers, int userId) {
10841        boolean waitingUpdate = false;
10842        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10843        List<ResolveInfo> ris = null;
10844        try {
10845            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10846                    intent, null, 0, userId);
10847        } catch (RemoteException e) {
10848        }
10849        if (ris != null) {
10850            for (int i=ris.size()-1; i>=0; i--) {
10851                if ((ris.get(i).activityInfo.applicationInfo.flags
10852                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10853                    ris.remove(i);
10854                }
10855            }
10856            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10857
10858            // For User 0, load the version number. When delivering to a new user, deliver
10859            // to all receivers.
10860            if (userId == UserHandle.USER_OWNER) {
10861                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10862                for (int i=0; i<ris.size(); i++) {
10863                    ActivityInfo ai = ris.get(i).activityInfo;
10864                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10865                    if (lastDoneReceivers.contains(comp)) {
10866                        // We already did the pre boot receiver for this app with the current
10867                        // platform version, so don't do it again...
10868                        ris.remove(i);
10869                        i--;
10870                        // ...however, do keep it as one that has been done, so we don't
10871                        // forget about it when rewriting the file of last done receivers.
10872                        doneReceivers.add(comp);
10873                    }
10874                }
10875            }
10876
10877            // If primary user, send broadcast to all available users, else just to userId
10878            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10879                    : new int[] { userId };
10880            for (int i = 0; i < ris.size(); i++) {
10881                ActivityInfo ai = ris.get(i).activityInfo;
10882                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10883                doneReceivers.add(comp);
10884                intent.setComponent(comp);
10885                for (int j=0; j<users.length; j++) {
10886                    IIntentReceiver finisher = null;
10887                    // On last receiver and user, set up a completion callback
10888                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10889                        finisher = new IIntentReceiver.Stub() {
10890                            public void performReceive(Intent intent, int resultCode,
10891                                    String data, Bundle extras, boolean ordered,
10892                                    boolean sticky, int sendingUser) {
10893                                // The raw IIntentReceiver interface is called
10894                                // with the AM lock held, so redispatch to
10895                                // execute our code without the lock.
10896                                mHandler.post(onFinishCallback);
10897                            }
10898                        };
10899                    }
10900                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10901                            + " for user " + users[j]);
10902                    broadcastIntentLocked(null, null, intent, null, finisher,
10903                            0, null, null, null, AppOpsManager.OP_NONE,
10904                            true, false, MY_PID, Process.SYSTEM_UID,
10905                            users[j]);
10906                    if (finisher != null) {
10907                        waitingUpdate = true;
10908                    }
10909                }
10910            }
10911        }
10912
10913        return waitingUpdate;
10914    }
10915
10916    public void systemReady(final Runnable goingCallback) {
10917        synchronized(this) {
10918            if (mSystemReady) {
10919                // If we're done calling all the receivers, run the next "boot phase" passed in
10920                // by the SystemServer
10921                if (goingCallback != null) {
10922                    goingCallback.run();
10923                }
10924                return;
10925            }
10926
10927            // Make sure we have the current profile info, since it is needed for
10928            // security checks.
10929            updateCurrentProfileIdsLocked();
10930
10931            if (mRecentTasks == null) {
10932                mRecentTasks = mTaskPersister.restoreTasksLocked();
10933                if (!mRecentTasks.isEmpty()) {
10934                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10935                }
10936                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10937                mTaskPersister.startPersisting();
10938            }
10939
10940            // Check to see if there are any update receivers to run.
10941            if (!mDidUpdate) {
10942                if (mWaitingUpdate) {
10943                    return;
10944                }
10945                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10946                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10947                    public void run() {
10948                        synchronized (ActivityManagerService.this) {
10949                            mDidUpdate = true;
10950                        }
10951                        writeLastDonePreBootReceivers(doneReceivers);
10952                        showBootMessage(mContext.getText(
10953                                R.string.android_upgrading_complete),
10954                                false);
10955                        systemReady(goingCallback);
10956                    }
10957                }, doneReceivers, UserHandle.USER_OWNER);
10958
10959                if (mWaitingUpdate) {
10960                    return;
10961                }
10962                mDidUpdate = true;
10963            }
10964
10965            mAppOpsService.systemReady();
10966            mSystemReady = true;
10967        }
10968
10969        ArrayList<ProcessRecord> procsToKill = null;
10970        synchronized(mPidsSelfLocked) {
10971            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10972                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10973                if (!isAllowedWhileBooting(proc.info)){
10974                    if (procsToKill == null) {
10975                        procsToKill = new ArrayList<ProcessRecord>();
10976                    }
10977                    procsToKill.add(proc);
10978                }
10979            }
10980        }
10981
10982        synchronized(this) {
10983            if (procsToKill != null) {
10984                for (int i=procsToKill.size()-1; i>=0; i--) {
10985                    ProcessRecord proc = procsToKill.get(i);
10986                    Slog.i(TAG, "Removing system update proc: " + proc);
10987                    removeProcessLocked(proc, true, false, "system update done");
10988                }
10989            }
10990
10991            // Now that we have cleaned up any update processes, we
10992            // are ready to start launching real processes and know that
10993            // we won't trample on them any more.
10994            mProcessesReady = true;
10995        }
10996
10997        Slog.i(TAG, "System now ready");
10998        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10999            SystemClock.uptimeMillis());
11000
11001        synchronized(this) {
11002            // Make sure we have no pre-ready processes sitting around.
11003
11004            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11005                ResolveInfo ri = mContext.getPackageManager()
11006                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11007                                STOCK_PM_FLAGS);
11008                CharSequence errorMsg = null;
11009                if (ri != null) {
11010                    ActivityInfo ai = ri.activityInfo;
11011                    ApplicationInfo app = ai.applicationInfo;
11012                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11013                        mTopAction = Intent.ACTION_FACTORY_TEST;
11014                        mTopData = null;
11015                        mTopComponent = new ComponentName(app.packageName,
11016                                ai.name);
11017                    } else {
11018                        errorMsg = mContext.getResources().getText(
11019                                com.android.internal.R.string.factorytest_not_system);
11020                    }
11021                } else {
11022                    errorMsg = mContext.getResources().getText(
11023                            com.android.internal.R.string.factorytest_no_action);
11024                }
11025                if (errorMsg != null) {
11026                    mTopAction = null;
11027                    mTopData = null;
11028                    mTopComponent = null;
11029                    Message msg = Message.obtain();
11030                    msg.what = SHOW_FACTORY_ERROR_MSG;
11031                    msg.getData().putCharSequence("msg", errorMsg);
11032                    mHandler.sendMessage(msg);
11033                }
11034            }
11035        }
11036
11037        retrieveSettings();
11038        loadResourcesOnSystemReady();
11039
11040        synchronized (this) {
11041            readGrantedUriPermissionsLocked();
11042        }
11043
11044        if (goingCallback != null) goingCallback.run();
11045
11046        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11047                Integer.toString(mCurrentUserId), mCurrentUserId);
11048        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11049                Integer.toString(mCurrentUserId), mCurrentUserId);
11050        mSystemServiceManager.startUser(mCurrentUserId);
11051
11052        synchronized (this) {
11053            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11054                try {
11055                    List apps = AppGlobals.getPackageManager().
11056                        getPersistentApplications(STOCK_PM_FLAGS);
11057                    if (apps != null) {
11058                        int N = apps.size();
11059                        int i;
11060                        for (i=0; i<N; i++) {
11061                            ApplicationInfo info
11062                                = (ApplicationInfo)apps.get(i);
11063                            if (info != null &&
11064                                    !info.packageName.equals("android")) {
11065                                addAppLocked(info, false, null /* ABI override */);
11066                            }
11067                        }
11068                    }
11069                } catch (RemoteException ex) {
11070                    // pm is in same process, this will never happen.
11071                }
11072            }
11073
11074            // Start up initial activity.
11075            mBooting = true;
11076
11077            try {
11078                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11079                    Message msg = Message.obtain();
11080                    msg.what = SHOW_UID_ERROR_MSG;
11081                    mHandler.sendMessage(msg);
11082                }
11083            } catch (RemoteException e) {
11084            }
11085
11086            long ident = Binder.clearCallingIdentity();
11087            try {
11088                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11089                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11090                        | Intent.FLAG_RECEIVER_FOREGROUND);
11091                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11092                broadcastIntentLocked(null, null, intent,
11093                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11094                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11095                intent = new Intent(Intent.ACTION_USER_STARTING);
11096                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11097                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11098                broadcastIntentLocked(null, null, intent,
11099                        null, new IIntentReceiver.Stub() {
11100                            @Override
11101                            public void performReceive(Intent intent, int resultCode, String data,
11102                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11103                                    throws RemoteException {
11104                            }
11105                        }, 0, null, null,
11106                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11107                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11108            } catch (Throwable t) {
11109                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11110            } finally {
11111                Binder.restoreCallingIdentity(ident);
11112            }
11113            mStackSupervisor.resumeTopActivitiesLocked();
11114            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11115        }
11116    }
11117
11118    private boolean makeAppCrashingLocked(ProcessRecord app,
11119            String shortMsg, String longMsg, String stackTrace) {
11120        app.crashing = true;
11121        app.crashingReport = generateProcessError(app,
11122                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11123        startAppProblemLocked(app);
11124        app.stopFreezingAllLocked();
11125        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11126    }
11127
11128    private void makeAppNotRespondingLocked(ProcessRecord app,
11129            String activity, String shortMsg, String longMsg) {
11130        app.notResponding = true;
11131        app.notRespondingReport = generateProcessError(app,
11132                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11133                activity, shortMsg, longMsg, null);
11134        startAppProblemLocked(app);
11135        app.stopFreezingAllLocked();
11136    }
11137
11138    /**
11139     * Generate a process error record, suitable for attachment to a ProcessRecord.
11140     *
11141     * @param app The ProcessRecord in which the error occurred.
11142     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11143     *                      ActivityManager.AppErrorStateInfo
11144     * @param activity The activity associated with the crash, if known.
11145     * @param shortMsg Short message describing the crash.
11146     * @param longMsg Long message describing the crash.
11147     * @param stackTrace Full crash stack trace, may be null.
11148     *
11149     * @return Returns a fully-formed AppErrorStateInfo record.
11150     */
11151    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11152            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11153        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11154
11155        report.condition = condition;
11156        report.processName = app.processName;
11157        report.pid = app.pid;
11158        report.uid = app.info.uid;
11159        report.tag = activity;
11160        report.shortMsg = shortMsg;
11161        report.longMsg = longMsg;
11162        report.stackTrace = stackTrace;
11163
11164        return report;
11165    }
11166
11167    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11168        synchronized (this) {
11169            app.crashing = false;
11170            app.crashingReport = null;
11171            app.notResponding = false;
11172            app.notRespondingReport = null;
11173            if (app.anrDialog == fromDialog) {
11174                app.anrDialog = null;
11175            }
11176            if (app.waitDialog == fromDialog) {
11177                app.waitDialog = null;
11178            }
11179            if (app.pid > 0 && app.pid != MY_PID) {
11180                handleAppCrashLocked(app, null, null, null);
11181                app.kill("user request after error", true);
11182            }
11183        }
11184    }
11185
11186    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11187            String stackTrace) {
11188        long now = SystemClock.uptimeMillis();
11189
11190        Long crashTime;
11191        if (!app.isolated) {
11192            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11193        } else {
11194            crashTime = null;
11195        }
11196        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11197            // This process loses!
11198            Slog.w(TAG, "Process " + app.info.processName
11199                    + " has crashed too many times: killing!");
11200            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11201                    app.userId, app.info.processName, app.uid);
11202            mStackSupervisor.handleAppCrashLocked(app);
11203            if (!app.persistent) {
11204                // We don't want to start this process again until the user
11205                // explicitly does so...  but for persistent process, we really
11206                // need to keep it running.  If a persistent process is actually
11207                // repeatedly crashing, then badness for everyone.
11208                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11209                        app.info.processName);
11210                if (!app.isolated) {
11211                    // XXX We don't have a way to mark isolated processes
11212                    // as bad, since they don't have a peristent identity.
11213                    mBadProcesses.put(app.info.processName, app.uid,
11214                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11215                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11216                }
11217                app.bad = true;
11218                app.removed = true;
11219                // Don't let services in this process be restarted and potentially
11220                // annoy the user repeatedly.  Unless it is persistent, since those
11221                // processes run critical code.
11222                removeProcessLocked(app, false, false, "crash");
11223                mStackSupervisor.resumeTopActivitiesLocked();
11224                return false;
11225            }
11226            mStackSupervisor.resumeTopActivitiesLocked();
11227        } else {
11228            mStackSupervisor.finishTopRunningActivityLocked(app);
11229        }
11230
11231        // Bump up the crash count of any services currently running in the proc.
11232        for (int i=app.services.size()-1; i>=0; i--) {
11233            // Any services running in the application need to be placed
11234            // back in the pending list.
11235            ServiceRecord sr = app.services.valueAt(i);
11236            sr.crashCount++;
11237        }
11238
11239        // If the crashing process is what we consider to be the "home process" and it has been
11240        // replaced by a third-party app, clear the package preferred activities from packages
11241        // with a home activity running in the process to prevent a repeatedly crashing app
11242        // from blocking the user to manually clear the list.
11243        final ArrayList<ActivityRecord> activities = app.activities;
11244        if (app == mHomeProcess && activities.size() > 0
11245                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11246            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11247                final ActivityRecord r = activities.get(activityNdx);
11248                if (r.isHomeActivity()) {
11249                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11250                    try {
11251                        ActivityThread.getPackageManager()
11252                                .clearPackagePreferredActivities(r.packageName);
11253                    } catch (RemoteException c) {
11254                        // pm is in same process, this will never happen.
11255                    }
11256                }
11257            }
11258        }
11259
11260        if (!app.isolated) {
11261            // XXX Can't keep track of crash times for isolated processes,
11262            // because they don't have a perisistent identity.
11263            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11264        }
11265
11266        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11267        return true;
11268    }
11269
11270    void startAppProblemLocked(ProcessRecord app) {
11271        // If this app is not running under the current user, then we
11272        // can't give it a report button because that would require
11273        // launching the report UI under a different user.
11274        app.errorReportReceiver = null;
11275
11276        for (int userId : mCurrentProfileIds) {
11277            if (app.userId == userId) {
11278                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11279                        mContext, app.info.packageName, app.info.flags);
11280            }
11281        }
11282        skipCurrentReceiverLocked(app);
11283    }
11284
11285    void skipCurrentReceiverLocked(ProcessRecord app) {
11286        for (BroadcastQueue queue : mBroadcastQueues) {
11287            queue.skipCurrentReceiverLocked(app);
11288        }
11289    }
11290
11291    /**
11292     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11293     * The application process will exit immediately after this call returns.
11294     * @param app object of the crashing app, null for the system server
11295     * @param crashInfo describing the exception
11296     */
11297    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11298        ProcessRecord r = findAppProcess(app, "Crash");
11299        final String processName = app == null ? "system_server"
11300                : (r == null ? "unknown" : r.processName);
11301
11302        handleApplicationCrashInner("crash", r, processName, crashInfo);
11303    }
11304
11305    /* Native crash reporting uses this inner version because it needs to be somewhat
11306     * decoupled from the AM-managed cleanup lifecycle
11307     */
11308    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11309            ApplicationErrorReport.CrashInfo crashInfo) {
11310        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11311                UserHandle.getUserId(Binder.getCallingUid()), processName,
11312                r == null ? -1 : r.info.flags,
11313                crashInfo.exceptionClassName,
11314                crashInfo.exceptionMessage,
11315                crashInfo.throwFileName,
11316                crashInfo.throwLineNumber);
11317
11318        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11319
11320        crashApplication(r, crashInfo);
11321    }
11322
11323    public void handleApplicationStrictModeViolation(
11324            IBinder app,
11325            int violationMask,
11326            StrictMode.ViolationInfo info) {
11327        ProcessRecord r = findAppProcess(app, "StrictMode");
11328        if (r == null) {
11329            return;
11330        }
11331
11332        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11333            Integer stackFingerprint = info.hashCode();
11334            boolean logIt = true;
11335            synchronized (mAlreadyLoggedViolatedStacks) {
11336                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11337                    logIt = false;
11338                    // TODO: sub-sample into EventLog for these, with
11339                    // the info.durationMillis?  Then we'd get
11340                    // the relative pain numbers, without logging all
11341                    // the stack traces repeatedly.  We'd want to do
11342                    // likewise in the client code, which also does
11343                    // dup suppression, before the Binder call.
11344                } else {
11345                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11346                        mAlreadyLoggedViolatedStacks.clear();
11347                    }
11348                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11349                }
11350            }
11351            if (logIt) {
11352                logStrictModeViolationToDropBox(r, info);
11353            }
11354        }
11355
11356        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11357            AppErrorResult result = new AppErrorResult();
11358            synchronized (this) {
11359                final long origId = Binder.clearCallingIdentity();
11360
11361                Message msg = Message.obtain();
11362                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11363                HashMap<String, Object> data = new HashMap<String, Object>();
11364                data.put("result", result);
11365                data.put("app", r);
11366                data.put("violationMask", violationMask);
11367                data.put("info", info);
11368                msg.obj = data;
11369                mHandler.sendMessage(msg);
11370
11371                Binder.restoreCallingIdentity(origId);
11372            }
11373            int res = result.get();
11374            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11375        }
11376    }
11377
11378    // Depending on the policy in effect, there could be a bunch of
11379    // these in quick succession so we try to batch these together to
11380    // minimize disk writes, number of dropbox entries, and maximize
11381    // compression, by having more fewer, larger records.
11382    private void logStrictModeViolationToDropBox(
11383            ProcessRecord process,
11384            StrictMode.ViolationInfo info) {
11385        if (info == null) {
11386            return;
11387        }
11388        final boolean isSystemApp = process == null ||
11389                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11390                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11391        final String processName = process == null ? "unknown" : process.processName;
11392        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11393        final DropBoxManager dbox = (DropBoxManager)
11394                mContext.getSystemService(Context.DROPBOX_SERVICE);
11395
11396        // Exit early if the dropbox isn't configured to accept this report type.
11397        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11398
11399        boolean bufferWasEmpty;
11400        boolean needsFlush;
11401        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11402        synchronized (sb) {
11403            bufferWasEmpty = sb.length() == 0;
11404            appendDropBoxProcessHeaders(process, processName, sb);
11405            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11406            sb.append("System-App: ").append(isSystemApp).append("\n");
11407            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11408            if (info.violationNumThisLoop != 0) {
11409                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11410            }
11411            if (info.numAnimationsRunning != 0) {
11412                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11413            }
11414            if (info.broadcastIntentAction != null) {
11415                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11416            }
11417            if (info.durationMillis != -1) {
11418                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11419            }
11420            if (info.numInstances != -1) {
11421                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11422            }
11423            if (info.tags != null) {
11424                for (String tag : info.tags) {
11425                    sb.append("Span-Tag: ").append(tag).append("\n");
11426                }
11427            }
11428            sb.append("\n");
11429            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11430                sb.append(info.crashInfo.stackTrace);
11431            }
11432            sb.append("\n");
11433
11434            // Only buffer up to ~64k.  Various logging bits truncate
11435            // things at 128k.
11436            needsFlush = (sb.length() > 64 * 1024);
11437        }
11438
11439        // Flush immediately if the buffer's grown too large, or this
11440        // is a non-system app.  Non-system apps are isolated with a
11441        // different tag & policy and not batched.
11442        //
11443        // Batching is useful during internal testing with
11444        // StrictMode settings turned up high.  Without batching,
11445        // thousands of separate files could be created on boot.
11446        if (!isSystemApp || needsFlush) {
11447            new Thread("Error dump: " + dropboxTag) {
11448                @Override
11449                public void run() {
11450                    String report;
11451                    synchronized (sb) {
11452                        report = sb.toString();
11453                        sb.delete(0, sb.length());
11454                        sb.trimToSize();
11455                    }
11456                    if (report.length() != 0) {
11457                        dbox.addText(dropboxTag, report);
11458                    }
11459                }
11460            }.start();
11461            return;
11462        }
11463
11464        // System app batching:
11465        if (!bufferWasEmpty) {
11466            // An existing dropbox-writing thread is outstanding, so
11467            // we don't need to start it up.  The existing thread will
11468            // catch the buffer appends we just did.
11469            return;
11470        }
11471
11472        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11473        // (After this point, we shouldn't access AMS internal data structures.)
11474        new Thread("Error dump: " + dropboxTag) {
11475            @Override
11476            public void run() {
11477                // 5 second sleep to let stacks arrive and be batched together
11478                try {
11479                    Thread.sleep(5000);  // 5 seconds
11480                } catch (InterruptedException e) {}
11481
11482                String errorReport;
11483                synchronized (mStrictModeBuffer) {
11484                    errorReport = mStrictModeBuffer.toString();
11485                    if (errorReport.length() == 0) {
11486                        return;
11487                    }
11488                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11489                    mStrictModeBuffer.trimToSize();
11490                }
11491                dbox.addText(dropboxTag, errorReport);
11492            }
11493        }.start();
11494    }
11495
11496    /**
11497     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11498     * @param app object of the crashing app, null for the system server
11499     * @param tag reported by the caller
11500     * @param system whether this wtf is coming from the system
11501     * @param crashInfo describing the context of the error
11502     * @return true if the process should exit immediately (WTF is fatal)
11503     */
11504    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11505            final ApplicationErrorReport.CrashInfo crashInfo) {
11506        final ProcessRecord r = findAppProcess(app, "WTF");
11507        final String processName = app == null ? "system_server"
11508                : (r == null ? "unknown" : r.processName);
11509
11510        EventLog.writeEvent(EventLogTags.AM_WTF,
11511                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11512                processName,
11513                r == null ? -1 : r.info.flags,
11514                tag, crashInfo.exceptionMessage);
11515
11516        if (system) {
11517            // If this is coming from the system, we could very well have low-level
11518            // system locks held, so we want to do this all asynchronously.  And we
11519            // never want this to become fatal, so there is that too.
11520            mHandler.post(new Runnable() {
11521                @Override public void run() {
11522                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11523                            crashInfo);
11524                }
11525            });
11526            return false;
11527        }
11528
11529        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11530
11531        if (r != null && r.pid != Process.myPid() &&
11532                Settings.Global.getInt(mContext.getContentResolver(),
11533                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11534            crashApplication(r, crashInfo);
11535            return true;
11536        } else {
11537            return false;
11538        }
11539    }
11540
11541    /**
11542     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11543     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11544     */
11545    private ProcessRecord findAppProcess(IBinder app, String reason) {
11546        if (app == null) {
11547            return null;
11548        }
11549
11550        synchronized (this) {
11551            final int NP = mProcessNames.getMap().size();
11552            for (int ip=0; ip<NP; ip++) {
11553                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11554                final int NA = apps.size();
11555                for (int ia=0; ia<NA; ia++) {
11556                    ProcessRecord p = apps.valueAt(ia);
11557                    if (p.thread != null && p.thread.asBinder() == app) {
11558                        return p;
11559                    }
11560                }
11561            }
11562
11563            Slog.w(TAG, "Can't find mystery application for " + reason
11564                    + " from pid=" + Binder.getCallingPid()
11565                    + " uid=" + Binder.getCallingUid() + ": " + app);
11566            return null;
11567        }
11568    }
11569
11570    /**
11571     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11572     * to append various headers to the dropbox log text.
11573     */
11574    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11575            StringBuilder sb) {
11576        // Watchdog thread ends up invoking this function (with
11577        // a null ProcessRecord) to add the stack file to dropbox.
11578        // Do not acquire a lock on this (am) in such cases, as it
11579        // could cause a potential deadlock, if and when watchdog
11580        // is invoked due to unavailability of lock on am and it
11581        // would prevent watchdog from killing system_server.
11582        if (process == null) {
11583            sb.append("Process: ").append(processName).append("\n");
11584            return;
11585        }
11586        // Note: ProcessRecord 'process' is guarded by the service
11587        // instance.  (notably process.pkgList, which could otherwise change
11588        // concurrently during execution of this method)
11589        synchronized (this) {
11590            sb.append("Process: ").append(processName).append("\n");
11591            int flags = process.info.flags;
11592            IPackageManager pm = AppGlobals.getPackageManager();
11593            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11594            for (int ip=0; ip<process.pkgList.size(); ip++) {
11595                String pkg = process.pkgList.keyAt(ip);
11596                sb.append("Package: ").append(pkg);
11597                try {
11598                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11599                    if (pi != null) {
11600                        sb.append(" v").append(pi.versionCode);
11601                        if (pi.versionName != null) {
11602                            sb.append(" (").append(pi.versionName).append(")");
11603                        }
11604                    }
11605                } catch (RemoteException e) {
11606                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11607                }
11608                sb.append("\n");
11609            }
11610        }
11611    }
11612
11613    private static String processClass(ProcessRecord process) {
11614        if (process == null || process.pid == MY_PID) {
11615            return "system_server";
11616        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11617            return "system_app";
11618        } else {
11619            return "data_app";
11620        }
11621    }
11622
11623    /**
11624     * Write a description of an error (crash, WTF, ANR) to the drop box.
11625     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11626     * @param process which caused the error, null means the system server
11627     * @param activity which triggered the error, null if unknown
11628     * @param parent activity related to the error, null if unknown
11629     * @param subject line related to the error, null if absent
11630     * @param report in long form describing the error, null if absent
11631     * @param logFile to include in the report, null if none
11632     * @param crashInfo giving an application stack trace, null if absent
11633     */
11634    public void addErrorToDropBox(String eventType,
11635            ProcessRecord process, String processName, ActivityRecord activity,
11636            ActivityRecord parent, String subject,
11637            final String report, final File logFile,
11638            final ApplicationErrorReport.CrashInfo crashInfo) {
11639        // NOTE -- this must never acquire the ActivityManagerService lock,
11640        // otherwise the watchdog may be prevented from resetting the system.
11641
11642        final String dropboxTag = processClass(process) + "_" + eventType;
11643        final DropBoxManager dbox = (DropBoxManager)
11644                mContext.getSystemService(Context.DROPBOX_SERVICE);
11645
11646        // Exit early if the dropbox isn't configured to accept this report type.
11647        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11648
11649        final StringBuilder sb = new StringBuilder(1024);
11650        appendDropBoxProcessHeaders(process, processName, sb);
11651        if (activity != null) {
11652            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11653        }
11654        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11655            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11656        }
11657        if (parent != null && parent != activity) {
11658            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11659        }
11660        if (subject != null) {
11661            sb.append("Subject: ").append(subject).append("\n");
11662        }
11663        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11664        if (Debug.isDebuggerConnected()) {
11665            sb.append("Debugger: Connected\n");
11666        }
11667        sb.append("\n");
11668
11669        // Do the rest in a worker thread to avoid blocking the caller on I/O
11670        // (After this point, we shouldn't access AMS internal data structures.)
11671        Thread worker = new Thread("Error dump: " + dropboxTag) {
11672            @Override
11673            public void run() {
11674                if (report != null) {
11675                    sb.append(report);
11676                }
11677                if (logFile != null) {
11678                    try {
11679                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11680                                    "\n\n[[TRUNCATED]]"));
11681                    } catch (IOException e) {
11682                        Slog.e(TAG, "Error reading " + logFile, e);
11683                    }
11684                }
11685                if (crashInfo != null && crashInfo.stackTrace != null) {
11686                    sb.append(crashInfo.stackTrace);
11687                }
11688
11689                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11690                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11691                if (lines > 0) {
11692                    sb.append("\n");
11693
11694                    // Merge several logcat streams, and take the last N lines
11695                    InputStreamReader input = null;
11696                    try {
11697                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11698                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11699                                "-b", "crash",
11700                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11701
11702                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11703                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11704                        input = new InputStreamReader(logcat.getInputStream());
11705
11706                        int num;
11707                        char[] buf = new char[8192];
11708                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11709                    } catch (IOException e) {
11710                        Slog.e(TAG, "Error running logcat", e);
11711                    } finally {
11712                        if (input != null) try { input.close(); } catch (IOException e) {}
11713                    }
11714                }
11715
11716                dbox.addText(dropboxTag, sb.toString());
11717            }
11718        };
11719
11720        if (process == null) {
11721            // If process is null, we are being called from some internal code
11722            // and may be about to die -- run this synchronously.
11723            worker.run();
11724        } else {
11725            worker.start();
11726        }
11727    }
11728
11729    /**
11730     * Bring up the "unexpected error" dialog box for a crashing app.
11731     * Deal with edge cases (intercepts from instrumented applications,
11732     * ActivityController, error intent receivers, that sort of thing).
11733     * @param r the application crashing
11734     * @param crashInfo describing the failure
11735     */
11736    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11737        long timeMillis = System.currentTimeMillis();
11738        String shortMsg = crashInfo.exceptionClassName;
11739        String longMsg = crashInfo.exceptionMessage;
11740        String stackTrace = crashInfo.stackTrace;
11741        if (shortMsg != null && longMsg != null) {
11742            longMsg = shortMsg + ": " + longMsg;
11743        } else if (shortMsg != null) {
11744            longMsg = shortMsg;
11745        }
11746
11747        AppErrorResult result = new AppErrorResult();
11748        synchronized (this) {
11749            if (mController != null) {
11750                try {
11751                    String name = r != null ? r.processName : null;
11752                    int pid = r != null ? r.pid : Binder.getCallingPid();
11753                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11754                    if (!mController.appCrashed(name, pid,
11755                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11756                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11757                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11758                            Slog.w(TAG, "Skip killing native crashed app " + name
11759                                    + "(" + pid + ") during testing");
11760                        } else {
11761                            Slog.w(TAG, "Force-killing crashed app " + name
11762                                    + " at watcher's request");
11763                            if (r != null) {
11764                                r.kill("crash", true);
11765                            } else {
11766                                // Huh.
11767                                Process.killProcess(pid);
11768                                Process.killProcessGroup(uid, pid);
11769                            }
11770                        }
11771                        return;
11772                    }
11773                } catch (RemoteException e) {
11774                    mController = null;
11775                    Watchdog.getInstance().setActivityController(null);
11776                }
11777            }
11778
11779            final long origId = Binder.clearCallingIdentity();
11780
11781            // If this process is running instrumentation, finish it.
11782            if (r != null && r.instrumentationClass != null) {
11783                Slog.w(TAG, "Error in app " + r.processName
11784                      + " running instrumentation " + r.instrumentationClass + ":");
11785                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11786                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11787                Bundle info = new Bundle();
11788                info.putString("shortMsg", shortMsg);
11789                info.putString("longMsg", longMsg);
11790                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11791                Binder.restoreCallingIdentity(origId);
11792                return;
11793            }
11794
11795            // If we can't identify the process or it's already exceeded its crash quota,
11796            // quit right away without showing a crash dialog.
11797            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11798                Binder.restoreCallingIdentity(origId);
11799                return;
11800            }
11801
11802            Message msg = Message.obtain();
11803            msg.what = SHOW_ERROR_MSG;
11804            HashMap data = new HashMap();
11805            data.put("result", result);
11806            data.put("app", r);
11807            msg.obj = data;
11808            mHandler.sendMessage(msg);
11809
11810            Binder.restoreCallingIdentity(origId);
11811        }
11812
11813        int res = result.get();
11814
11815        Intent appErrorIntent = null;
11816        synchronized (this) {
11817            if (r != null && !r.isolated) {
11818                // XXX Can't keep track of crash time for isolated processes,
11819                // since they don't have a persistent identity.
11820                mProcessCrashTimes.put(r.info.processName, r.uid,
11821                        SystemClock.uptimeMillis());
11822            }
11823            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11824                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11825            }
11826        }
11827
11828        if (appErrorIntent != null) {
11829            try {
11830                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11831            } catch (ActivityNotFoundException e) {
11832                Slog.w(TAG, "bug report receiver dissappeared", e);
11833            }
11834        }
11835    }
11836
11837    Intent createAppErrorIntentLocked(ProcessRecord r,
11838            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11839        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11840        if (report == null) {
11841            return null;
11842        }
11843        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11844        result.setComponent(r.errorReportReceiver);
11845        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11846        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11847        return result;
11848    }
11849
11850    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11851            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11852        if (r.errorReportReceiver == null) {
11853            return null;
11854        }
11855
11856        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11857            return null;
11858        }
11859
11860        ApplicationErrorReport report = new ApplicationErrorReport();
11861        report.packageName = r.info.packageName;
11862        report.installerPackageName = r.errorReportReceiver.getPackageName();
11863        report.processName = r.processName;
11864        report.time = timeMillis;
11865        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11866
11867        if (r.crashing || r.forceCrashReport) {
11868            report.type = ApplicationErrorReport.TYPE_CRASH;
11869            report.crashInfo = crashInfo;
11870        } else if (r.notResponding) {
11871            report.type = ApplicationErrorReport.TYPE_ANR;
11872            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11873
11874            report.anrInfo.activity = r.notRespondingReport.tag;
11875            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11876            report.anrInfo.info = r.notRespondingReport.longMsg;
11877        }
11878
11879        return report;
11880    }
11881
11882    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11883        enforceNotIsolatedCaller("getProcessesInErrorState");
11884        // assume our apps are happy - lazy create the list
11885        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11886
11887        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11888                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11889        int userId = UserHandle.getUserId(Binder.getCallingUid());
11890
11891        synchronized (this) {
11892
11893            // iterate across all processes
11894            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11895                ProcessRecord app = mLruProcesses.get(i);
11896                if (!allUsers && app.userId != userId) {
11897                    continue;
11898                }
11899                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11900                    // This one's in trouble, so we'll generate a report for it
11901                    // crashes are higher priority (in case there's a crash *and* an anr)
11902                    ActivityManager.ProcessErrorStateInfo report = null;
11903                    if (app.crashing) {
11904                        report = app.crashingReport;
11905                    } else if (app.notResponding) {
11906                        report = app.notRespondingReport;
11907                    }
11908
11909                    if (report != null) {
11910                        if (errList == null) {
11911                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11912                        }
11913                        errList.add(report);
11914                    } else {
11915                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11916                                " crashing = " + app.crashing +
11917                                " notResponding = " + app.notResponding);
11918                    }
11919                }
11920            }
11921        }
11922
11923        return errList;
11924    }
11925
11926    static int procStateToImportance(int procState, int memAdj,
11927            ActivityManager.RunningAppProcessInfo currApp) {
11928        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11929        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11930            currApp.lru = memAdj;
11931        } else {
11932            currApp.lru = 0;
11933        }
11934        return imp;
11935    }
11936
11937    private void fillInProcMemInfo(ProcessRecord app,
11938            ActivityManager.RunningAppProcessInfo outInfo) {
11939        outInfo.pid = app.pid;
11940        outInfo.uid = app.info.uid;
11941        if (mHeavyWeightProcess == app) {
11942            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11943        }
11944        if (app.persistent) {
11945            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11946        }
11947        if (app.activities.size() > 0) {
11948            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11949        }
11950        outInfo.lastTrimLevel = app.trimMemoryLevel;
11951        int adj = app.curAdj;
11952        int procState = app.curProcState;
11953        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11954        outInfo.importanceReasonCode = app.adjTypeCode;
11955        outInfo.processState = app.curProcState;
11956    }
11957
11958    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11959        enforceNotIsolatedCaller("getRunningAppProcesses");
11960        // Lazy instantiation of list
11961        List<ActivityManager.RunningAppProcessInfo> runList = null;
11962        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11963                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11964        int userId = UserHandle.getUserId(Binder.getCallingUid());
11965        synchronized (this) {
11966            // Iterate across all processes
11967            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11968                ProcessRecord app = mLruProcesses.get(i);
11969                if (!allUsers && app.userId != userId) {
11970                    continue;
11971                }
11972                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11973                    // Generate process state info for running application
11974                    ActivityManager.RunningAppProcessInfo currApp =
11975                        new ActivityManager.RunningAppProcessInfo(app.processName,
11976                                app.pid, app.getPackageList());
11977                    fillInProcMemInfo(app, currApp);
11978                    if (app.adjSource instanceof ProcessRecord) {
11979                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11980                        currApp.importanceReasonImportance =
11981                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11982                                        app.adjSourceProcState);
11983                    } else if (app.adjSource instanceof ActivityRecord) {
11984                        ActivityRecord r = (ActivityRecord)app.adjSource;
11985                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11986                    }
11987                    if (app.adjTarget instanceof ComponentName) {
11988                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11989                    }
11990                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11991                    //        + " lru=" + currApp.lru);
11992                    if (runList == null) {
11993                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11994                    }
11995                    runList.add(currApp);
11996                }
11997            }
11998        }
11999        return runList;
12000    }
12001
12002    public List<ApplicationInfo> getRunningExternalApplications() {
12003        enforceNotIsolatedCaller("getRunningExternalApplications");
12004        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12005        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12006        if (runningApps != null && runningApps.size() > 0) {
12007            Set<String> extList = new HashSet<String>();
12008            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12009                if (app.pkgList != null) {
12010                    for (String pkg : app.pkgList) {
12011                        extList.add(pkg);
12012                    }
12013                }
12014            }
12015            IPackageManager pm = AppGlobals.getPackageManager();
12016            for (String pkg : extList) {
12017                try {
12018                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12019                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12020                        retList.add(info);
12021                    }
12022                } catch (RemoteException e) {
12023                }
12024            }
12025        }
12026        return retList;
12027    }
12028
12029    @Override
12030    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12031        enforceNotIsolatedCaller("getMyMemoryState");
12032        synchronized (this) {
12033            ProcessRecord proc;
12034            synchronized (mPidsSelfLocked) {
12035                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12036            }
12037            fillInProcMemInfo(proc, outInfo);
12038        }
12039    }
12040
12041    @Override
12042    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12043        if (checkCallingPermission(android.Manifest.permission.DUMP)
12044                != PackageManager.PERMISSION_GRANTED) {
12045            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12046                    + Binder.getCallingPid()
12047                    + ", uid=" + Binder.getCallingUid()
12048                    + " without permission "
12049                    + android.Manifest.permission.DUMP);
12050            return;
12051        }
12052
12053        boolean dumpAll = false;
12054        boolean dumpClient = false;
12055        String dumpPackage = null;
12056
12057        int opti = 0;
12058        while (opti < args.length) {
12059            String opt = args[opti];
12060            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12061                break;
12062            }
12063            opti++;
12064            if ("-a".equals(opt)) {
12065                dumpAll = true;
12066            } else if ("-c".equals(opt)) {
12067                dumpClient = true;
12068            } else if ("-h".equals(opt)) {
12069                pw.println("Activity manager dump options:");
12070                pw.println("  [-a] [-c] [-h] [cmd] ...");
12071                pw.println("  cmd may be one of:");
12072                pw.println("    a[ctivities]: activity stack state");
12073                pw.println("    r[recents]: recent activities state");
12074                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12075                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12076                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12077                pw.println("    o[om]: out of memory management");
12078                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12079                pw.println("    provider [COMP_SPEC]: provider client-side state");
12080                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12081                pw.println("    service [COMP_SPEC]: service client-side state");
12082                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12083                pw.println("    all: dump all activities");
12084                pw.println("    top: dump the top activity");
12085                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12086                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12087                pw.println("    a partial substring in a component name, a");
12088                pw.println("    hex object identifier.");
12089                pw.println("  -a: include all available server state.");
12090                pw.println("  -c: include client state.");
12091                return;
12092            } else {
12093                pw.println("Unknown argument: " + opt + "; use -h for help");
12094            }
12095        }
12096
12097        long origId = Binder.clearCallingIdentity();
12098        boolean more = false;
12099        // Is the caller requesting to dump a particular piece of data?
12100        if (opti < args.length) {
12101            String cmd = args[opti];
12102            opti++;
12103            if ("activities".equals(cmd) || "a".equals(cmd)) {
12104                synchronized (this) {
12105                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12106                }
12107            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12108                synchronized (this) {
12109                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12110                }
12111            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12112                String[] newArgs;
12113                String name;
12114                if (opti >= args.length) {
12115                    name = null;
12116                    newArgs = EMPTY_STRING_ARRAY;
12117                } else {
12118                    name = args[opti];
12119                    opti++;
12120                    newArgs = new String[args.length - opti];
12121                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12122                            args.length - opti);
12123                }
12124                synchronized (this) {
12125                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12126                }
12127            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12128                String[] newArgs;
12129                String name;
12130                if (opti >= args.length) {
12131                    name = null;
12132                    newArgs = EMPTY_STRING_ARRAY;
12133                } else {
12134                    name = args[opti];
12135                    opti++;
12136                    newArgs = new String[args.length - opti];
12137                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12138                            args.length - opti);
12139                }
12140                synchronized (this) {
12141                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12142                }
12143            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12144                String[] newArgs;
12145                String name;
12146                if (opti >= args.length) {
12147                    name = null;
12148                    newArgs = EMPTY_STRING_ARRAY;
12149                } else {
12150                    name = args[opti];
12151                    opti++;
12152                    newArgs = new String[args.length - opti];
12153                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12154                            args.length - opti);
12155                }
12156                synchronized (this) {
12157                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12158                }
12159            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12160                synchronized (this) {
12161                    dumpOomLocked(fd, pw, args, opti, true);
12162                }
12163            } else if ("provider".equals(cmd)) {
12164                String[] newArgs;
12165                String name;
12166                if (opti >= args.length) {
12167                    name = null;
12168                    newArgs = EMPTY_STRING_ARRAY;
12169                } else {
12170                    name = args[opti];
12171                    opti++;
12172                    newArgs = new String[args.length - opti];
12173                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12174                }
12175                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12176                    pw.println("No providers match: " + name);
12177                    pw.println("Use -h for help.");
12178                }
12179            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12180                synchronized (this) {
12181                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12182                }
12183            } else if ("service".equals(cmd)) {
12184                String[] newArgs;
12185                String name;
12186                if (opti >= args.length) {
12187                    name = null;
12188                    newArgs = EMPTY_STRING_ARRAY;
12189                } else {
12190                    name = args[opti];
12191                    opti++;
12192                    newArgs = new String[args.length - opti];
12193                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12194                            args.length - opti);
12195                }
12196                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12197                    pw.println("No services match: " + name);
12198                    pw.println("Use -h for help.");
12199                }
12200            } else if ("package".equals(cmd)) {
12201                String[] newArgs;
12202                if (opti >= args.length) {
12203                    pw.println("package: no package name specified");
12204                    pw.println("Use -h for help.");
12205                } else {
12206                    dumpPackage = args[opti];
12207                    opti++;
12208                    newArgs = new String[args.length - opti];
12209                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12210                            args.length - opti);
12211                    args = newArgs;
12212                    opti = 0;
12213                    more = true;
12214                }
12215            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12216                synchronized (this) {
12217                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12218                }
12219            } else {
12220                // Dumping a single activity?
12221                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12222                    pw.println("Bad activity command, or no activities match: " + cmd);
12223                    pw.println("Use -h for help.");
12224                }
12225            }
12226            if (!more) {
12227                Binder.restoreCallingIdentity(origId);
12228                return;
12229            }
12230        }
12231
12232        // No piece of data specified, dump everything.
12233        synchronized (this) {
12234            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12235            pw.println();
12236            if (dumpAll) {
12237                pw.println("-------------------------------------------------------------------------------");
12238            }
12239            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12240            pw.println();
12241            if (dumpAll) {
12242                pw.println("-------------------------------------------------------------------------------");
12243            }
12244            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12245            pw.println();
12246            if (dumpAll) {
12247                pw.println("-------------------------------------------------------------------------------");
12248            }
12249            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12250            pw.println();
12251            if (dumpAll) {
12252                pw.println("-------------------------------------------------------------------------------");
12253            }
12254            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12255            pw.println();
12256            if (dumpAll) {
12257                pw.println("-------------------------------------------------------------------------------");
12258            }
12259            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12260            pw.println();
12261            if (dumpAll) {
12262                pw.println("-------------------------------------------------------------------------------");
12263            }
12264            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12265        }
12266        Binder.restoreCallingIdentity(origId);
12267    }
12268
12269    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12270            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12271        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12272
12273        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12274                dumpPackage);
12275        boolean needSep = printedAnything;
12276
12277        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12278                dumpPackage, needSep, "  mFocusedActivity: ");
12279        if (printed) {
12280            printedAnything = true;
12281            needSep = false;
12282        }
12283
12284        if (dumpPackage == null) {
12285            if (needSep) {
12286                pw.println();
12287            }
12288            needSep = true;
12289            printedAnything = true;
12290            mStackSupervisor.dump(pw, "  ");
12291        }
12292
12293        if (!printedAnything) {
12294            pw.println("  (nothing)");
12295        }
12296    }
12297
12298    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12299            int opti, boolean dumpAll, String dumpPackage) {
12300        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12301
12302        boolean printedAnything = false;
12303
12304        if (mRecentTasks.size() > 0) {
12305            boolean printedHeader = false;
12306
12307            final int N = mRecentTasks.size();
12308            for (int i=0; i<N; i++) {
12309                TaskRecord tr = mRecentTasks.get(i);
12310                if (dumpPackage != null) {
12311                    if (tr.realActivity == null ||
12312                            !dumpPackage.equals(tr.realActivity)) {
12313                        continue;
12314                    }
12315                }
12316                if (!printedHeader) {
12317                    pw.println("  Recent tasks:");
12318                    printedHeader = true;
12319                    printedAnything = true;
12320                }
12321                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12322                        pw.println(tr);
12323                if (dumpAll) {
12324                    mRecentTasks.get(i).dump(pw, "    ");
12325                }
12326            }
12327        }
12328
12329        if (!printedAnything) {
12330            pw.println("  (nothing)");
12331        }
12332    }
12333
12334    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12335            int opti, boolean dumpAll, String dumpPackage) {
12336        boolean needSep = false;
12337        boolean printedAnything = false;
12338        int numPers = 0;
12339
12340        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12341
12342        if (dumpAll) {
12343            final int NP = mProcessNames.getMap().size();
12344            for (int ip=0; ip<NP; ip++) {
12345                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12346                final int NA = procs.size();
12347                for (int ia=0; ia<NA; ia++) {
12348                    ProcessRecord r = procs.valueAt(ia);
12349                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12350                        continue;
12351                    }
12352                    if (!needSep) {
12353                        pw.println("  All known processes:");
12354                        needSep = true;
12355                        printedAnything = true;
12356                    }
12357                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12358                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12359                        pw.print(" "); pw.println(r);
12360                    r.dump(pw, "    ");
12361                    if (r.persistent) {
12362                        numPers++;
12363                    }
12364                }
12365            }
12366        }
12367
12368        if (mIsolatedProcesses.size() > 0) {
12369            boolean printed = false;
12370            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12371                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12372                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12373                    continue;
12374                }
12375                if (!printed) {
12376                    if (needSep) {
12377                        pw.println();
12378                    }
12379                    pw.println("  Isolated process list (sorted by uid):");
12380                    printedAnything = true;
12381                    printed = true;
12382                    needSep = true;
12383                }
12384                pw.println(String.format("%sIsolated #%2d: %s",
12385                        "    ", i, r.toString()));
12386            }
12387        }
12388
12389        if (mLruProcesses.size() > 0) {
12390            if (needSep) {
12391                pw.println();
12392            }
12393            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12394                    pw.print(" total, non-act at ");
12395                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12396                    pw.print(", non-svc at ");
12397                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12398                    pw.println("):");
12399            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12400            needSep = true;
12401            printedAnything = true;
12402        }
12403
12404        if (dumpAll || dumpPackage != null) {
12405            synchronized (mPidsSelfLocked) {
12406                boolean printed = false;
12407                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12408                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12409                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12410                        continue;
12411                    }
12412                    if (!printed) {
12413                        if (needSep) pw.println();
12414                        needSep = true;
12415                        pw.println("  PID mappings:");
12416                        printed = true;
12417                        printedAnything = true;
12418                    }
12419                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12420                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12421                }
12422            }
12423        }
12424
12425        if (mForegroundProcesses.size() > 0) {
12426            synchronized (mPidsSelfLocked) {
12427                boolean printed = false;
12428                for (int i=0; i<mForegroundProcesses.size(); i++) {
12429                    ProcessRecord r = mPidsSelfLocked.get(
12430                            mForegroundProcesses.valueAt(i).pid);
12431                    if (dumpPackage != null && (r == null
12432                            || !r.pkgList.containsKey(dumpPackage))) {
12433                        continue;
12434                    }
12435                    if (!printed) {
12436                        if (needSep) pw.println();
12437                        needSep = true;
12438                        pw.println("  Foreground Processes:");
12439                        printed = true;
12440                        printedAnything = true;
12441                    }
12442                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12443                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12444                }
12445            }
12446        }
12447
12448        if (mPersistentStartingProcesses.size() > 0) {
12449            if (needSep) pw.println();
12450            needSep = true;
12451            printedAnything = true;
12452            pw.println("  Persisent processes that are starting:");
12453            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12454                    "Starting Norm", "Restarting PERS", dumpPackage);
12455        }
12456
12457        if (mRemovedProcesses.size() > 0) {
12458            if (needSep) pw.println();
12459            needSep = true;
12460            printedAnything = true;
12461            pw.println("  Processes that are being removed:");
12462            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12463                    "Removed Norm", "Removed PERS", dumpPackage);
12464        }
12465
12466        if (mProcessesOnHold.size() > 0) {
12467            if (needSep) pw.println();
12468            needSep = true;
12469            printedAnything = true;
12470            pw.println("  Processes that are on old until the system is ready:");
12471            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12472                    "OnHold Norm", "OnHold PERS", dumpPackage);
12473        }
12474
12475        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12476
12477        if (mProcessCrashTimes.getMap().size() > 0) {
12478            boolean printed = false;
12479            long now = SystemClock.uptimeMillis();
12480            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12481            final int NP = pmap.size();
12482            for (int ip=0; ip<NP; ip++) {
12483                String pname = pmap.keyAt(ip);
12484                SparseArray<Long> uids = pmap.valueAt(ip);
12485                final int N = uids.size();
12486                for (int i=0; i<N; i++) {
12487                    int puid = uids.keyAt(i);
12488                    ProcessRecord r = mProcessNames.get(pname, puid);
12489                    if (dumpPackage != null && (r == null
12490                            || !r.pkgList.containsKey(dumpPackage))) {
12491                        continue;
12492                    }
12493                    if (!printed) {
12494                        if (needSep) pw.println();
12495                        needSep = true;
12496                        pw.println("  Time since processes crashed:");
12497                        printed = true;
12498                        printedAnything = true;
12499                    }
12500                    pw.print("    Process "); pw.print(pname);
12501                            pw.print(" uid "); pw.print(puid);
12502                            pw.print(": last crashed ");
12503                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12504                            pw.println(" ago");
12505                }
12506            }
12507        }
12508
12509        if (mBadProcesses.getMap().size() > 0) {
12510            boolean printed = false;
12511            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12512            final int NP = pmap.size();
12513            for (int ip=0; ip<NP; ip++) {
12514                String pname = pmap.keyAt(ip);
12515                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12516                final int N = uids.size();
12517                for (int i=0; i<N; i++) {
12518                    int puid = uids.keyAt(i);
12519                    ProcessRecord r = mProcessNames.get(pname, puid);
12520                    if (dumpPackage != null && (r == null
12521                            || !r.pkgList.containsKey(dumpPackage))) {
12522                        continue;
12523                    }
12524                    if (!printed) {
12525                        if (needSep) pw.println();
12526                        needSep = true;
12527                        pw.println("  Bad processes:");
12528                        printedAnything = true;
12529                    }
12530                    BadProcessInfo info = uids.valueAt(i);
12531                    pw.print("    Bad process "); pw.print(pname);
12532                            pw.print(" uid "); pw.print(puid);
12533                            pw.print(": crashed at time "); pw.println(info.time);
12534                    if (info.shortMsg != null) {
12535                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12536                    }
12537                    if (info.longMsg != null) {
12538                        pw.print("      Long msg: "); pw.println(info.longMsg);
12539                    }
12540                    if (info.stack != null) {
12541                        pw.println("      Stack:");
12542                        int lastPos = 0;
12543                        for (int pos=0; pos<info.stack.length(); pos++) {
12544                            if (info.stack.charAt(pos) == '\n') {
12545                                pw.print("        ");
12546                                pw.write(info.stack, lastPos, pos-lastPos);
12547                                pw.println();
12548                                lastPos = pos+1;
12549                            }
12550                        }
12551                        if (lastPos < info.stack.length()) {
12552                            pw.print("        ");
12553                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12554                            pw.println();
12555                        }
12556                    }
12557                }
12558            }
12559        }
12560
12561        if (dumpPackage == null) {
12562            pw.println();
12563            needSep = false;
12564            pw.println("  mStartedUsers:");
12565            for (int i=0; i<mStartedUsers.size(); i++) {
12566                UserStartedState uss = mStartedUsers.valueAt(i);
12567                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12568                        pw.print(": "); uss.dump("", pw);
12569            }
12570            pw.print("  mStartedUserArray: [");
12571            for (int i=0; i<mStartedUserArray.length; i++) {
12572                if (i > 0) pw.print(", ");
12573                pw.print(mStartedUserArray[i]);
12574            }
12575            pw.println("]");
12576            pw.print("  mUserLru: [");
12577            for (int i=0; i<mUserLru.size(); i++) {
12578                if (i > 0) pw.print(", ");
12579                pw.print(mUserLru.get(i));
12580            }
12581            pw.println("]");
12582            if (dumpAll) {
12583                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12584            }
12585            synchronized (mUserProfileGroupIdsSelfLocked) {
12586                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12587                    pw.println("  mUserProfileGroupIds:");
12588                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12589                        pw.print("    User #");
12590                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12591                        pw.print(" -> profile #");
12592                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12593                    }
12594                }
12595            }
12596        }
12597        if (mHomeProcess != null && (dumpPackage == null
12598                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12599            if (needSep) {
12600                pw.println();
12601                needSep = false;
12602            }
12603            pw.println("  mHomeProcess: " + mHomeProcess);
12604        }
12605        if (mPreviousProcess != null && (dumpPackage == null
12606                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12607            if (needSep) {
12608                pw.println();
12609                needSep = false;
12610            }
12611            pw.println("  mPreviousProcess: " + mPreviousProcess);
12612        }
12613        if (dumpAll) {
12614            StringBuilder sb = new StringBuilder(128);
12615            sb.append("  mPreviousProcessVisibleTime: ");
12616            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12617            pw.println(sb);
12618        }
12619        if (mHeavyWeightProcess != null && (dumpPackage == null
12620                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12621            if (needSep) {
12622                pw.println();
12623                needSep = false;
12624            }
12625            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12626        }
12627        if (dumpPackage == null) {
12628            pw.println("  mConfiguration: " + mConfiguration);
12629        }
12630        if (dumpAll) {
12631            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12632            if (mCompatModePackages.getPackages().size() > 0) {
12633                boolean printed = false;
12634                for (Map.Entry<String, Integer> entry
12635                        : mCompatModePackages.getPackages().entrySet()) {
12636                    String pkg = entry.getKey();
12637                    int mode = entry.getValue();
12638                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12639                        continue;
12640                    }
12641                    if (!printed) {
12642                        pw.println("  mScreenCompatPackages:");
12643                        printed = true;
12644                    }
12645                    pw.print("    "); pw.print(pkg); pw.print(": ");
12646                            pw.print(mode); pw.println();
12647                }
12648            }
12649        }
12650        if (dumpPackage == null) {
12651            if (mSleeping || mWentToSleep || mLockScreenShown) {
12652                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12653                        + " mLockScreenShown " + mLockScreenShown);
12654            }
12655            if (mShuttingDown || mRunningVoice) {
12656                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12657            }
12658        }
12659        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12660                || mOrigWaitForDebugger) {
12661            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12662                    || dumpPackage.equals(mOrigDebugApp)) {
12663                if (needSep) {
12664                    pw.println();
12665                    needSep = false;
12666                }
12667                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12668                        + " mDebugTransient=" + mDebugTransient
12669                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12670            }
12671        }
12672        if (mOpenGlTraceApp != null) {
12673            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12674                if (needSep) {
12675                    pw.println();
12676                    needSep = false;
12677                }
12678                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12679            }
12680        }
12681        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12682                || mProfileFd != null) {
12683            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12684                if (needSep) {
12685                    pw.println();
12686                    needSep = false;
12687                }
12688                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12689                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12690                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12691                        + mAutoStopProfiler);
12692                pw.println("  mProfileType=" + mProfileType);
12693            }
12694        }
12695        if (dumpPackage == null) {
12696            if (mAlwaysFinishActivities || mController != null) {
12697                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12698                        + " mController=" + mController);
12699            }
12700            if (dumpAll) {
12701                pw.println("  Total persistent processes: " + numPers);
12702                pw.println("  mProcessesReady=" + mProcessesReady
12703                        + " mSystemReady=" + mSystemReady);
12704                pw.println("  mBooting=" + mBooting
12705                        + " mBooted=" + mBooted
12706                        + " mFactoryTest=" + mFactoryTest);
12707                pw.print("  mLastPowerCheckRealtime=");
12708                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12709                        pw.println("");
12710                pw.print("  mLastPowerCheckUptime=");
12711                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12712                        pw.println("");
12713                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12714                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12715                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12716                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12717                        + " (" + mLruProcesses.size() + " total)"
12718                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12719                        + " mNumServiceProcs=" + mNumServiceProcs
12720                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12721                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12722                        + " mLastMemoryLevel" + mLastMemoryLevel
12723                        + " mLastNumProcesses" + mLastNumProcesses);
12724                long now = SystemClock.uptimeMillis();
12725                pw.print("  mLastIdleTime=");
12726                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12727                        pw.print(" mLowRamSinceLastIdle=");
12728                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12729                        pw.println();
12730            }
12731        }
12732
12733        if (!printedAnything) {
12734            pw.println("  (nothing)");
12735        }
12736    }
12737
12738    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12739            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12740        if (mProcessesToGc.size() > 0) {
12741            boolean printed = false;
12742            long now = SystemClock.uptimeMillis();
12743            for (int i=0; i<mProcessesToGc.size(); i++) {
12744                ProcessRecord proc = mProcessesToGc.get(i);
12745                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12746                    continue;
12747                }
12748                if (!printed) {
12749                    if (needSep) pw.println();
12750                    needSep = true;
12751                    pw.println("  Processes that are waiting to GC:");
12752                    printed = true;
12753                }
12754                pw.print("    Process "); pw.println(proc);
12755                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12756                        pw.print(", last gced=");
12757                        pw.print(now-proc.lastRequestedGc);
12758                        pw.print(" ms ago, last lowMem=");
12759                        pw.print(now-proc.lastLowMemory);
12760                        pw.println(" ms ago");
12761
12762            }
12763        }
12764        return needSep;
12765    }
12766
12767    void printOomLevel(PrintWriter pw, String name, int adj) {
12768        pw.print("    ");
12769        if (adj >= 0) {
12770            pw.print(' ');
12771            if (adj < 10) pw.print(' ');
12772        } else {
12773            if (adj > -10) pw.print(' ');
12774        }
12775        pw.print(adj);
12776        pw.print(": ");
12777        pw.print(name);
12778        pw.print(" (");
12779        pw.print(mProcessList.getMemLevel(adj)/1024);
12780        pw.println(" kB)");
12781    }
12782
12783    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12784            int opti, boolean dumpAll) {
12785        boolean needSep = false;
12786
12787        if (mLruProcesses.size() > 0) {
12788            if (needSep) pw.println();
12789            needSep = true;
12790            pw.println("  OOM levels:");
12791            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12792            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12793            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12794            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12795            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12796            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12797            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12798            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12799            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12800            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12801            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12802            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12803            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12804
12805            if (needSep) pw.println();
12806            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12807                    pw.print(" total, non-act at ");
12808                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12809                    pw.print(", non-svc at ");
12810                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12811                    pw.println("):");
12812            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12813            needSep = true;
12814        }
12815
12816        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12817
12818        pw.println();
12819        pw.println("  mHomeProcess: " + mHomeProcess);
12820        pw.println("  mPreviousProcess: " + mPreviousProcess);
12821        if (mHeavyWeightProcess != null) {
12822            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12823        }
12824
12825        return true;
12826    }
12827
12828    /**
12829     * There are three ways to call this:
12830     *  - no provider specified: dump all the providers
12831     *  - a flattened component name that matched an existing provider was specified as the
12832     *    first arg: dump that one provider
12833     *  - the first arg isn't the flattened component name of an existing provider:
12834     *    dump all providers whose component contains the first arg as a substring
12835     */
12836    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12837            int opti, boolean dumpAll) {
12838        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12839    }
12840
12841    static class ItemMatcher {
12842        ArrayList<ComponentName> components;
12843        ArrayList<String> strings;
12844        ArrayList<Integer> objects;
12845        boolean all;
12846
12847        ItemMatcher() {
12848            all = true;
12849        }
12850
12851        void build(String name) {
12852            ComponentName componentName = ComponentName.unflattenFromString(name);
12853            if (componentName != null) {
12854                if (components == null) {
12855                    components = new ArrayList<ComponentName>();
12856                }
12857                components.add(componentName);
12858                all = false;
12859            } else {
12860                int objectId = 0;
12861                // Not a '/' separated full component name; maybe an object ID?
12862                try {
12863                    objectId = Integer.parseInt(name, 16);
12864                    if (objects == null) {
12865                        objects = new ArrayList<Integer>();
12866                    }
12867                    objects.add(objectId);
12868                    all = false;
12869                } catch (RuntimeException e) {
12870                    // Not an integer; just do string match.
12871                    if (strings == null) {
12872                        strings = new ArrayList<String>();
12873                    }
12874                    strings.add(name);
12875                    all = false;
12876                }
12877            }
12878        }
12879
12880        int build(String[] args, int opti) {
12881            for (; opti<args.length; opti++) {
12882                String name = args[opti];
12883                if ("--".equals(name)) {
12884                    return opti+1;
12885                }
12886                build(name);
12887            }
12888            return opti;
12889        }
12890
12891        boolean match(Object object, ComponentName comp) {
12892            if (all) {
12893                return true;
12894            }
12895            if (components != null) {
12896                for (int i=0; i<components.size(); i++) {
12897                    if (components.get(i).equals(comp)) {
12898                        return true;
12899                    }
12900                }
12901            }
12902            if (objects != null) {
12903                for (int i=0; i<objects.size(); i++) {
12904                    if (System.identityHashCode(object) == objects.get(i)) {
12905                        return true;
12906                    }
12907                }
12908            }
12909            if (strings != null) {
12910                String flat = comp.flattenToString();
12911                for (int i=0; i<strings.size(); i++) {
12912                    if (flat.contains(strings.get(i))) {
12913                        return true;
12914                    }
12915                }
12916            }
12917            return false;
12918        }
12919    }
12920
12921    /**
12922     * There are three things that cmd can be:
12923     *  - a flattened component name that matches an existing activity
12924     *  - the cmd arg isn't the flattened component name of an existing activity:
12925     *    dump all activity whose component contains the cmd as a substring
12926     *  - A hex number of the ActivityRecord object instance.
12927     */
12928    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12929            int opti, boolean dumpAll) {
12930        ArrayList<ActivityRecord> activities;
12931
12932        synchronized (this) {
12933            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12934        }
12935
12936        if (activities.size() <= 0) {
12937            return false;
12938        }
12939
12940        String[] newArgs = new String[args.length - opti];
12941        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12942
12943        TaskRecord lastTask = null;
12944        boolean needSep = false;
12945        for (int i=activities.size()-1; i>=0; i--) {
12946            ActivityRecord r = activities.get(i);
12947            if (needSep) {
12948                pw.println();
12949            }
12950            needSep = true;
12951            synchronized (this) {
12952                if (lastTask != r.task) {
12953                    lastTask = r.task;
12954                    pw.print("TASK "); pw.print(lastTask.affinity);
12955                            pw.print(" id="); pw.println(lastTask.taskId);
12956                    if (dumpAll) {
12957                        lastTask.dump(pw, "  ");
12958                    }
12959                }
12960            }
12961            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12962        }
12963        return true;
12964    }
12965
12966    /**
12967     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12968     * there is a thread associated with the activity.
12969     */
12970    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12971            final ActivityRecord r, String[] args, boolean dumpAll) {
12972        String innerPrefix = prefix + "  ";
12973        synchronized (this) {
12974            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12975                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12976                    pw.print(" pid=");
12977                    if (r.app != null) pw.println(r.app.pid);
12978                    else pw.println("(not running)");
12979            if (dumpAll) {
12980                r.dump(pw, innerPrefix);
12981            }
12982        }
12983        if (r.app != null && r.app.thread != null) {
12984            // flush anything that is already in the PrintWriter since the thread is going
12985            // to write to the file descriptor directly
12986            pw.flush();
12987            try {
12988                TransferPipe tp = new TransferPipe();
12989                try {
12990                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12991                            r.appToken, innerPrefix, args);
12992                    tp.go(fd);
12993                } finally {
12994                    tp.kill();
12995                }
12996            } catch (IOException e) {
12997                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12998            } catch (RemoteException e) {
12999                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13000            }
13001        }
13002    }
13003
13004    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13005            int opti, boolean dumpAll, String dumpPackage) {
13006        boolean needSep = false;
13007        boolean onlyHistory = false;
13008        boolean printedAnything = false;
13009
13010        if ("history".equals(dumpPackage)) {
13011            if (opti < args.length && "-s".equals(args[opti])) {
13012                dumpAll = false;
13013            }
13014            onlyHistory = true;
13015            dumpPackage = null;
13016        }
13017
13018        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13019        if (!onlyHistory && dumpAll) {
13020            if (mRegisteredReceivers.size() > 0) {
13021                boolean printed = false;
13022                Iterator it = mRegisteredReceivers.values().iterator();
13023                while (it.hasNext()) {
13024                    ReceiverList r = (ReceiverList)it.next();
13025                    if (dumpPackage != null && (r.app == null ||
13026                            !dumpPackage.equals(r.app.info.packageName))) {
13027                        continue;
13028                    }
13029                    if (!printed) {
13030                        pw.println("  Registered Receivers:");
13031                        needSep = true;
13032                        printed = true;
13033                        printedAnything = true;
13034                    }
13035                    pw.print("  * "); pw.println(r);
13036                    r.dump(pw, "    ");
13037                }
13038            }
13039
13040            if (mReceiverResolver.dump(pw, needSep ?
13041                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13042                    "    ", dumpPackage, false)) {
13043                needSep = true;
13044                printedAnything = true;
13045            }
13046        }
13047
13048        for (BroadcastQueue q : mBroadcastQueues) {
13049            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13050            printedAnything |= needSep;
13051        }
13052
13053        needSep = true;
13054
13055        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13056            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13057                if (needSep) {
13058                    pw.println();
13059                }
13060                needSep = true;
13061                printedAnything = true;
13062                pw.print("  Sticky broadcasts for user ");
13063                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13064                StringBuilder sb = new StringBuilder(128);
13065                for (Map.Entry<String, ArrayList<Intent>> ent
13066                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13067                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13068                    if (dumpAll) {
13069                        pw.println(":");
13070                        ArrayList<Intent> intents = ent.getValue();
13071                        final int N = intents.size();
13072                        for (int i=0; i<N; i++) {
13073                            sb.setLength(0);
13074                            sb.append("    Intent: ");
13075                            intents.get(i).toShortString(sb, false, true, false, false);
13076                            pw.println(sb.toString());
13077                            Bundle bundle = intents.get(i).getExtras();
13078                            if (bundle != null) {
13079                                pw.print("      ");
13080                                pw.println(bundle.toString());
13081                            }
13082                        }
13083                    } else {
13084                        pw.println("");
13085                    }
13086                }
13087            }
13088        }
13089
13090        if (!onlyHistory && dumpAll) {
13091            pw.println();
13092            for (BroadcastQueue queue : mBroadcastQueues) {
13093                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13094                        + queue.mBroadcastsScheduled);
13095            }
13096            pw.println("  mHandler:");
13097            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13098            needSep = true;
13099            printedAnything = true;
13100        }
13101
13102        if (!printedAnything) {
13103            pw.println("  (nothing)");
13104        }
13105    }
13106
13107    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13108            int opti, boolean dumpAll, String dumpPackage) {
13109        boolean needSep;
13110        boolean printedAnything = false;
13111
13112        ItemMatcher matcher = new ItemMatcher();
13113        matcher.build(args, opti);
13114
13115        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13116
13117        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13118        printedAnything |= needSep;
13119
13120        if (mLaunchingProviders.size() > 0) {
13121            boolean printed = false;
13122            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13123                ContentProviderRecord r = mLaunchingProviders.get(i);
13124                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13125                    continue;
13126                }
13127                if (!printed) {
13128                    if (needSep) pw.println();
13129                    needSep = true;
13130                    pw.println("  Launching content providers:");
13131                    printed = true;
13132                    printedAnything = true;
13133                }
13134                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13135                        pw.println(r);
13136            }
13137        }
13138
13139        if (mGrantedUriPermissions.size() > 0) {
13140            boolean printed = false;
13141            int dumpUid = -2;
13142            if (dumpPackage != null) {
13143                try {
13144                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13145                } catch (NameNotFoundException e) {
13146                    dumpUid = -1;
13147                }
13148            }
13149            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13150                int uid = mGrantedUriPermissions.keyAt(i);
13151                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13152                    continue;
13153                }
13154                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13155                if (!printed) {
13156                    if (needSep) pw.println();
13157                    needSep = true;
13158                    pw.println("  Granted Uri Permissions:");
13159                    printed = true;
13160                    printedAnything = true;
13161                }
13162                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13163                for (UriPermission perm : perms.values()) {
13164                    pw.print("    "); pw.println(perm);
13165                    if (dumpAll) {
13166                        perm.dump(pw, "      ");
13167                    }
13168                }
13169            }
13170        }
13171
13172        if (!printedAnything) {
13173            pw.println("  (nothing)");
13174        }
13175    }
13176
13177    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13178            int opti, boolean dumpAll, String dumpPackage) {
13179        boolean printed = false;
13180
13181        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13182
13183        if (mIntentSenderRecords.size() > 0) {
13184            Iterator<WeakReference<PendingIntentRecord>> it
13185                    = mIntentSenderRecords.values().iterator();
13186            while (it.hasNext()) {
13187                WeakReference<PendingIntentRecord> ref = it.next();
13188                PendingIntentRecord rec = ref != null ? ref.get(): null;
13189                if (dumpPackage != null && (rec == null
13190                        || !dumpPackage.equals(rec.key.packageName))) {
13191                    continue;
13192                }
13193                printed = true;
13194                if (rec != null) {
13195                    pw.print("  * "); pw.println(rec);
13196                    if (dumpAll) {
13197                        rec.dump(pw, "    ");
13198                    }
13199                } else {
13200                    pw.print("  * "); pw.println(ref);
13201                }
13202            }
13203        }
13204
13205        if (!printed) {
13206            pw.println("  (nothing)");
13207        }
13208    }
13209
13210    private static final int dumpProcessList(PrintWriter pw,
13211            ActivityManagerService service, List list,
13212            String prefix, String normalLabel, String persistentLabel,
13213            String dumpPackage) {
13214        int numPers = 0;
13215        final int N = list.size()-1;
13216        for (int i=N; i>=0; i--) {
13217            ProcessRecord r = (ProcessRecord)list.get(i);
13218            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13219                continue;
13220            }
13221            pw.println(String.format("%s%s #%2d: %s",
13222                    prefix, (r.persistent ? persistentLabel : normalLabel),
13223                    i, r.toString()));
13224            if (r.persistent) {
13225                numPers++;
13226            }
13227        }
13228        return numPers;
13229    }
13230
13231    private static final boolean dumpProcessOomList(PrintWriter pw,
13232            ActivityManagerService service, List<ProcessRecord> origList,
13233            String prefix, String normalLabel, String persistentLabel,
13234            boolean inclDetails, String dumpPackage) {
13235
13236        ArrayList<Pair<ProcessRecord, Integer>> list
13237                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13238        for (int i=0; i<origList.size(); i++) {
13239            ProcessRecord r = origList.get(i);
13240            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13241                continue;
13242            }
13243            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13244        }
13245
13246        if (list.size() <= 0) {
13247            return false;
13248        }
13249
13250        Comparator<Pair<ProcessRecord, Integer>> comparator
13251                = new Comparator<Pair<ProcessRecord, Integer>>() {
13252            @Override
13253            public int compare(Pair<ProcessRecord, Integer> object1,
13254                    Pair<ProcessRecord, Integer> object2) {
13255                if (object1.first.setAdj != object2.first.setAdj) {
13256                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13257                }
13258                if (object1.second.intValue() != object2.second.intValue()) {
13259                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13260                }
13261                return 0;
13262            }
13263        };
13264
13265        Collections.sort(list, comparator);
13266
13267        final long curRealtime = SystemClock.elapsedRealtime();
13268        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13269        final long curUptime = SystemClock.uptimeMillis();
13270        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13271
13272        for (int i=list.size()-1; i>=0; i--) {
13273            ProcessRecord r = list.get(i).first;
13274            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13275            char schedGroup;
13276            switch (r.setSchedGroup) {
13277                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13278                    schedGroup = 'B';
13279                    break;
13280                case Process.THREAD_GROUP_DEFAULT:
13281                    schedGroup = 'F';
13282                    break;
13283                default:
13284                    schedGroup = '?';
13285                    break;
13286            }
13287            char foreground;
13288            if (r.foregroundActivities) {
13289                foreground = 'A';
13290            } else if (r.foregroundServices) {
13291                foreground = 'S';
13292            } else {
13293                foreground = ' ';
13294            }
13295            String procState = ProcessList.makeProcStateString(r.curProcState);
13296            pw.print(prefix);
13297            pw.print(r.persistent ? persistentLabel : normalLabel);
13298            pw.print(" #");
13299            int num = (origList.size()-1)-list.get(i).second;
13300            if (num < 10) pw.print(' ');
13301            pw.print(num);
13302            pw.print(": ");
13303            pw.print(oomAdj);
13304            pw.print(' ');
13305            pw.print(schedGroup);
13306            pw.print('/');
13307            pw.print(foreground);
13308            pw.print('/');
13309            pw.print(procState);
13310            pw.print(" trm:");
13311            if (r.trimMemoryLevel < 10) pw.print(' ');
13312            pw.print(r.trimMemoryLevel);
13313            pw.print(' ');
13314            pw.print(r.toShortString());
13315            pw.print(" (");
13316            pw.print(r.adjType);
13317            pw.println(')');
13318            if (r.adjSource != null || r.adjTarget != null) {
13319                pw.print(prefix);
13320                pw.print("    ");
13321                if (r.adjTarget instanceof ComponentName) {
13322                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13323                } else if (r.adjTarget != null) {
13324                    pw.print(r.adjTarget.toString());
13325                } else {
13326                    pw.print("{null}");
13327                }
13328                pw.print("<=");
13329                if (r.adjSource instanceof ProcessRecord) {
13330                    pw.print("Proc{");
13331                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13332                    pw.println("}");
13333                } else if (r.adjSource != null) {
13334                    pw.println(r.adjSource.toString());
13335                } else {
13336                    pw.println("{null}");
13337                }
13338            }
13339            if (inclDetails) {
13340                pw.print(prefix);
13341                pw.print("    ");
13342                pw.print("oom: max="); pw.print(r.maxAdj);
13343                pw.print(" curRaw="); pw.print(r.curRawAdj);
13344                pw.print(" setRaw="); pw.print(r.setRawAdj);
13345                pw.print(" cur="); pw.print(r.curAdj);
13346                pw.print(" set="); pw.println(r.setAdj);
13347                pw.print(prefix);
13348                pw.print("    ");
13349                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13350                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13351                pw.print(" lastPss="); pw.print(r.lastPss);
13352                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13353                pw.print(prefix);
13354                pw.print("    ");
13355                pw.print("cached="); pw.print(r.cached);
13356                pw.print(" empty="); pw.print(r.empty);
13357                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13358
13359                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13360                    if (r.lastWakeTime != 0) {
13361                        long wtime;
13362                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13363                        synchronized (stats) {
13364                            wtime = stats.getProcessWakeTime(r.info.uid,
13365                                    r.pid, curRealtime);
13366                        }
13367                        long timeUsed = wtime - r.lastWakeTime;
13368                        pw.print(prefix);
13369                        pw.print("    ");
13370                        pw.print("keep awake over ");
13371                        TimeUtils.formatDuration(realtimeSince, pw);
13372                        pw.print(" used ");
13373                        TimeUtils.formatDuration(timeUsed, pw);
13374                        pw.print(" (");
13375                        pw.print((timeUsed*100)/realtimeSince);
13376                        pw.println("%)");
13377                    }
13378                    if (r.lastCpuTime != 0) {
13379                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13380                        pw.print(prefix);
13381                        pw.print("    ");
13382                        pw.print("run cpu over ");
13383                        TimeUtils.formatDuration(uptimeSince, pw);
13384                        pw.print(" used ");
13385                        TimeUtils.formatDuration(timeUsed, pw);
13386                        pw.print(" (");
13387                        pw.print((timeUsed*100)/uptimeSince);
13388                        pw.println("%)");
13389                    }
13390                }
13391            }
13392        }
13393        return true;
13394    }
13395
13396    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13397        ArrayList<ProcessRecord> procs;
13398        synchronized (this) {
13399            if (args != null && args.length > start
13400                    && args[start].charAt(0) != '-') {
13401                procs = new ArrayList<ProcessRecord>();
13402                int pid = -1;
13403                try {
13404                    pid = Integer.parseInt(args[start]);
13405                } catch (NumberFormatException e) {
13406                }
13407                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13408                    ProcessRecord proc = mLruProcesses.get(i);
13409                    if (proc.pid == pid) {
13410                        procs.add(proc);
13411                    } else if (proc.processName.equals(args[start])) {
13412                        procs.add(proc);
13413                    }
13414                }
13415                if (procs.size() <= 0) {
13416                    return null;
13417                }
13418            } else {
13419                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13420            }
13421        }
13422        return procs;
13423    }
13424
13425    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13426            PrintWriter pw, String[] args) {
13427        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13428        if (procs == null) {
13429            pw.println("No process found for: " + args[0]);
13430            return;
13431        }
13432
13433        long uptime = SystemClock.uptimeMillis();
13434        long realtime = SystemClock.elapsedRealtime();
13435        pw.println("Applications Graphics Acceleration Info:");
13436        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13437
13438        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13439            ProcessRecord r = procs.get(i);
13440            if (r.thread != null) {
13441                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13442                pw.flush();
13443                try {
13444                    TransferPipe tp = new TransferPipe();
13445                    try {
13446                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13447                        tp.go(fd);
13448                    } finally {
13449                        tp.kill();
13450                    }
13451                } catch (IOException e) {
13452                    pw.println("Failure while dumping the app: " + r);
13453                    pw.flush();
13454                } catch (RemoteException e) {
13455                    pw.println("Got a RemoteException while dumping the app " + r);
13456                    pw.flush();
13457                }
13458            }
13459        }
13460    }
13461
13462    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13463        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13464        if (procs == null) {
13465            pw.println("No process found for: " + args[0]);
13466            return;
13467        }
13468
13469        pw.println("Applications Database Info:");
13470
13471        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13472            ProcessRecord r = procs.get(i);
13473            if (r.thread != null) {
13474                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13475                pw.flush();
13476                try {
13477                    TransferPipe tp = new TransferPipe();
13478                    try {
13479                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13480                        tp.go(fd);
13481                    } finally {
13482                        tp.kill();
13483                    }
13484                } catch (IOException e) {
13485                    pw.println("Failure while dumping the app: " + r);
13486                    pw.flush();
13487                } catch (RemoteException e) {
13488                    pw.println("Got a RemoteException while dumping the app " + r);
13489                    pw.flush();
13490                }
13491            }
13492        }
13493    }
13494
13495    final static class MemItem {
13496        final boolean isProc;
13497        final String label;
13498        final String shortLabel;
13499        final long pss;
13500        final int id;
13501        final boolean hasActivities;
13502        ArrayList<MemItem> subitems;
13503
13504        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13505                boolean _hasActivities) {
13506            isProc = true;
13507            label = _label;
13508            shortLabel = _shortLabel;
13509            pss = _pss;
13510            id = _id;
13511            hasActivities = _hasActivities;
13512        }
13513
13514        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13515            isProc = false;
13516            label = _label;
13517            shortLabel = _shortLabel;
13518            pss = _pss;
13519            id = _id;
13520            hasActivities = false;
13521        }
13522    }
13523
13524    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13525            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13526        if (sort && !isCompact) {
13527            Collections.sort(items, new Comparator<MemItem>() {
13528                @Override
13529                public int compare(MemItem lhs, MemItem rhs) {
13530                    if (lhs.pss < rhs.pss) {
13531                        return 1;
13532                    } else if (lhs.pss > rhs.pss) {
13533                        return -1;
13534                    }
13535                    return 0;
13536                }
13537            });
13538        }
13539
13540        for (int i=0; i<items.size(); i++) {
13541            MemItem mi = items.get(i);
13542            if (!isCompact) {
13543                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13544            } else if (mi.isProc) {
13545                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13546                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13547                pw.println(mi.hasActivities ? ",a" : ",e");
13548            } else {
13549                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13550                pw.println(mi.pss);
13551            }
13552            if (mi.subitems != null) {
13553                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13554                        true, isCompact);
13555            }
13556        }
13557    }
13558
13559    // These are in KB.
13560    static final long[] DUMP_MEM_BUCKETS = new long[] {
13561        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13562        120*1024, 160*1024, 200*1024,
13563        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13564        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13565    };
13566
13567    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13568            boolean stackLike) {
13569        int start = label.lastIndexOf('.');
13570        if (start >= 0) start++;
13571        else start = 0;
13572        int end = label.length();
13573        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13574            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13575                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13576                out.append(bucket);
13577                out.append(stackLike ? "MB." : "MB ");
13578                out.append(label, start, end);
13579                return;
13580            }
13581        }
13582        out.append(memKB/1024);
13583        out.append(stackLike ? "MB." : "MB ");
13584        out.append(label, start, end);
13585    }
13586
13587    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13588            ProcessList.NATIVE_ADJ,
13589            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13590            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13591            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13592            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13593            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13594    };
13595    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13596            "Native",
13597            "System", "Persistent", "Foreground",
13598            "Visible", "Perceptible",
13599            "Heavy Weight", "Backup",
13600            "A Services", "Home",
13601            "Previous", "B Services", "Cached"
13602    };
13603    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13604            "native",
13605            "sys", "pers", "fore",
13606            "vis", "percept",
13607            "heavy", "backup",
13608            "servicea", "home",
13609            "prev", "serviceb", "cached"
13610    };
13611
13612    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13613            long realtime, boolean isCheckinRequest, boolean isCompact) {
13614        if (isCheckinRequest || isCompact) {
13615            // short checkin version
13616            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13617        } else {
13618            pw.println("Applications Memory Usage (kB):");
13619            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13620        }
13621    }
13622
13623    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13624            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13625        boolean dumpDetails = false;
13626        boolean dumpFullDetails = false;
13627        boolean dumpDalvik = false;
13628        boolean oomOnly = false;
13629        boolean isCompact = false;
13630        boolean localOnly = false;
13631
13632        int opti = 0;
13633        while (opti < args.length) {
13634            String opt = args[opti];
13635            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13636                break;
13637            }
13638            opti++;
13639            if ("-a".equals(opt)) {
13640                dumpDetails = true;
13641                dumpFullDetails = true;
13642                dumpDalvik = true;
13643            } else if ("-d".equals(opt)) {
13644                dumpDalvik = true;
13645            } else if ("-c".equals(opt)) {
13646                isCompact = true;
13647            } else if ("--oom".equals(opt)) {
13648                oomOnly = true;
13649            } else if ("--local".equals(opt)) {
13650                localOnly = true;
13651            } else if ("-h".equals(opt)) {
13652                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13653                pw.println("  -a: include all available information for each process.");
13654                pw.println("  -d: include dalvik details when dumping process details.");
13655                pw.println("  -c: dump in a compact machine-parseable representation.");
13656                pw.println("  --oom: only show processes organized by oom adj.");
13657                pw.println("  --local: only collect details locally, don't call process.");
13658                pw.println("If [process] is specified it can be the name or ");
13659                pw.println("pid of a specific process to dump.");
13660                return;
13661            } else {
13662                pw.println("Unknown argument: " + opt + "; use -h for help");
13663            }
13664        }
13665
13666        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13667        long uptime = SystemClock.uptimeMillis();
13668        long realtime = SystemClock.elapsedRealtime();
13669        final long[] tmpLong = new long[1];
13670
13671        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13672        if (procs == null) {
13673            // No Java processes.  Maybe they want to print a native process.
13674            if (args != null && args.length > opti
13675                    && args[opti].charAt(0) != '-') {
13676                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13677                        = new ArrayList<ProcessCpuTracker.Stats>();
13678                updateCpuStatsNow();
13679                int findPid = -1;
13680                try {
13681                    findPid = Integer.parseInt(args[opti]);
13682                } catch (NumberFormatException e) {
13683                }
13684                synchronized (mProcessCpuThread) {
13685                    final int N = mProcessCpuTracker.countStats();
13686                    for (int i=0; i<N; i++) {
13687                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13688                        if (st.pid == findPid || (st.baseName != null
13689                                && st.baseName.equals(args[opti]))) {
13690                            nativeProcs.add(st);
13691                        }
13692                    }
13693                }
13694                if (nativeProcs.size() > 0) {
13695                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13696                            isCompact);
13697                    Debug.MemoryInfo mi = null;
13698                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13699                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13700                        final int pid = r.pid;
13701                        if (!isCheckinRequest && dumpDetails) {
13702                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13703                        }
13704                        if (mi == null) {
13705                            mi = new Debug.MemoryInfo();
13706                        }
13707                        if (dumpDetails || (!brief && !oomOnly)) {
13708                            Debug.getMemoryInfo(pid, mi);
13709                        } else {
13710                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13711                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13712                        }
13713                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13714                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13715                        if (isCheckinRequest) {
13716                            pw.println();
13717                        }
13718                    }
13719                    return;
13720                }
13721            }
13722            pw.println("No process found for: " + args[opti]);
13723            return;
13724        }
13725
13726        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13727            dumpDetails = true;
13728        }
13729
13730        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13731
13732        String[] innerArgs = new String[args.length-opti];
13733        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13734
13735        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13736        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13737        long nativePss=0, dalvikPss=0, otherPss=0;
13738        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13739
13740        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13741        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13742                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13743
13744        long totalPss = 0;
13745        long cachedPss = 0;
13746
13747        Debug.MemoryInfo mi = null;
13748        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13749            final ProcessRecord r = procs.get(i);
13750            final IApplicationThread thread;
13751            final int pid;
13752            final int oomAdj;
13753            final boolean hasActivities;
13754            synchronized (this) {
13755                thread = r.thread;
13756                pid = r.pid;
13757                oomAdj = r.getSetAdjWithServices();
13758                hasActivities = r.activities.size() > 0;
13759            }
13760            if (thread != null) {
13761                if (!isCheckinRequest && dumpDetails) {
13762                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13763                }
13764                if (mi == null) {
13765                    mi = new Debug.MemoryInfo();
13766                }
13767                if (dumpDetails || (!brief && !oomOnly)) {
13768                    Debug.getMemoryInfo(pid, mi);
13769                } else {
13770                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13771                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13772                }
13773                if (dumpDetails) {
13774                    if (localOnly) {
13775                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13776                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13777                        if (isCheckinRequest) {
13778                            pw.println();
13779                        }
13780                    } else {
13781                        try {
13782                            pw.flush();
13783                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13784                                    dumpDalvik, innerArgs);
13785                        } catch (RemoteException e) {
13786                            if (!isCheckinRequest) {
13787                                pw.println("Got RemoteException!");
13788                                pw.flush();
13789                            }
13790                        }
13791                    }
13792                }
13793
13794                final long myTotalPss = mi.getTotalPss();
13795                final long myTotalUss = mi.getTotalUss();
13796
13797                synchronized (this) {
13798                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13799                        // Record this for posterity if the process has been stable.
13800                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13801                    }
13802                }
13803
13804                if (!isCheckinRequest && mi != null) {
13805                    totalPss += myTotalPss;
13806                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13807                            (hasActivities ? " / activities)" : ")"),
13808                            r.processName, myTotalPss, pid, hasActivities);
13809                    procMems.add(pssItem);
13810                    procMemsMap.put(pid, pssItem);
13811
13812                    nativePss += mi.nativePss;
13813                    dalvikPss += mi.dalvikPss;
13814                    otherPss += mi.otherPss;
13815                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13816                        long mem = mi.getOtherPss(j);
13817                        miscPss[j] += mem;
13818                        otherPss -= mem;
13819                    }
13820
13821                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13822                        cachedPss += myTotalPss;
13823                    }
13824
13825                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13826                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13827                                || oomIndex == (oomPss.length-1)) {
13828                            oomPss[oomIndex] += myTotalPss;
13829                            if (oomProcs[oomIndex] == null) {
13830                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13831                            }
13832                            oomProcs[oomIndex].add(pssItem);
13833                            break;
13834                        }
13835                    }
13836                }
13837            }
13838        }
13839
13840        long nativeProcTotalPss = 0;
13841
13842        if (!isCheckinRequest && procs.size() > 1) {
13843            // If we are showing aggregations, also look for native processes to
13844            // include so that our aggregations are more accurate.
13845            updateCpuStatsNow();
13846            synchronized (mProcessCpuThread) {
13847                final int N = mProcessCpuTracker.countStats();
13848                for (int i=0; i<N; i++) {
13849                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13850                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13851                        if (mi == null) {
13852                            mi = new Debug.MemoryInfo();
13853                        }
13854                        if (!brief && !oomOnly) {
13855                            Debug.getMemoryInfo(st.pid, mi);
13856                        } else {
13857                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13858                            mi.nativePrivateDirty = (int)tmpLong[0];
13859                        }
13860
13861                        final long myTotalPss = mi.getTotalPss();
13862                        totalPss += myTotalPss;
13863                        nativeProcTotalPss += myTotalPss;
13864
13865                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13866                                st.name, myTotalPss, st.pid, false);
13867                        procMems.add(pssItem);
13868
13869                        nativePss += mi.nativePss;
13870                        dalvikPss += mi.dalvikPss;
13871                        otherPss += mi.otherPss;
13872                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13873                            long mem = mi.getOtherPss(j);
13874                            miscPss[j] += mem;
13875                            otherPss -= mem;
13876                        }
13877                        oomPss[0] += myTotalPss;
13878                        if (oomProcs[0] == null) {
13879                            oomProcs[0] = new ArrayList<MemItem>();
13880                        }
13881                        oomProcs[0].add(pssItem);
13882                    }
13883                }
13884            }
13885
13886            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13887
13888            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13889            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13890            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13891            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13892                String label = Debug.MemoryInfo.getOtherLabel(j);
13893                catMems.add(new MemItem(label, label, miscPss[j], j));
13894            }
13895
13896            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13897            for (int j=0; j<oomPss.length; j++) {
13898                if (oomPss[j] != 0) {
13899                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13900                            : DUMP_MEM_OOM_LABEL[j];
13901                    MemItem item = new MemItem(label, label, oomPss[j],
13902                            DUMP_MEM_OOM_ADJ[j]);
13903                    item.subitems = oomProcs[j];
13904                    oomMems.add(item);
13905                }
13906            }
13907
13908            if (!brief && !oomOnly && !isCompact) {
13909                pw.println();
13910                pw.println("Total PSS by process:");
13911                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13912                pw.println();
13913            }
13914            if (!isCompact) {
13915                pw.println("Total PSS by OOM adjustment:");
13916            }
13917            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13918            if (!brief && !oomOnly) {
13919                PrintWriter out = categoryPw != null ? categoryPw : pw;
13920                if (!isCompact) {
13921                    out.println();
13922                    out.println("Total PSS by category:");
13923                }
13924                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13925            }
13926            if (!isCompact) {
13927                pw.println();
13928            }
13929            MemInfoReader memInfo = new MemInfoReader();
13930            memInfo.readMemInfo();
13931            if (nativeProcTotalPss > 0) {
13932                synchronized (this) {
13933                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13934                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13935                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13936                            nativeProcTotalPss);
13937                }
13938            }
13939            if (!brief) {
13940                if (!isCompact) {
13941                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13942                    pw.print(" kB (status ");
13943                    switch (mLastMemoryLevel) {
13944                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13945                            pw.println("normal)");
13946                            break;
13947                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13948                            pw.println("moderate)");
13949                            break;
13950                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13951                            pw.println("low)");
13952                            break;
13953                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13954                            pw.println("critical)");
13955                            break;
13956                        default:
13957                            pw.print(mLastMemoryLevel);
13958                            pw.println(")");
13959                            break;
13960                    }
13961                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13962                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13963                            pw.print(cachedPss); pw.print(" cached pss + ");
13964                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13965                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13966                } else {
13967                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13968                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13969                            + memInfo.getFreeSizeKb()); pw.print(",");
13970                    pw.println(totalPss - cachedPss);
13971                }
13972            }
13973            if (!isCompact) {
13974                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13975                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13976                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13977                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13978                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13979                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13980                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13981                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13982                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13983                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13984                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13985            }
13986            if (!brief) {
13987                if (memInfo.getZramTotalSizeKb() != 0) {
13988                    if (!isCompact) {
13989                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13990                                pw.print(" kB physical used for ");
13991                                pw.print(memInfo.getSwapTotalSizeKb()
13992                                        - memInfo.getSwapFreeSizeKb());
13993                                pw.print(" kB in swap (");
13994                                pw.print(memInfo.getSwapTotalSizeKb());
13995                                pw.println(" kB total swap)");
13996                    } else {
13997                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13998                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13999                                pw.println(memInfo.getSwapFreeSizeKb());
14000                    }
14001                }
14002                final int[] SINGLE_LONG_FORMAT = new int[] {
14003                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14004                };
14005                long[] longOut = new long[1];
14006                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14007                        SINGLE_LONG_FORMAT, null, longOut, null);
14008                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14009                longOut[0] = 0;
14010                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14011                        SINGLE_LONG_FORMAT, null, longOut, null);
14012                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14013                longOut[0] = 0;
14014                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14015                        SINGLE_LONG_FORMAT, null, longOut, null);
14016                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14017                longOut[0] = 0;
14018                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14019                        SINGLE_LONG_FORMAT, null, longOut, null);
14020                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14021                if (!isCompact) {
14022                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14023                        pw.print("      KSM: "); pw.print(sharing);
14024                                pw.print(" kB saved from shared ");
14025                                pw.print(shared); pw.println(" kB");
14026                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14027                                pw.print(voltile); pw.println(" kB volatile");
14028                    }
14029                    pw.print("   Tuning: ");
14030                    pw.print(ActivityManager.staticGetMemoryClass());
14031                    pw.print(" (large ");
14032                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14033                    pw.print("), oom ");
14034                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14035                    pw.print(" kB");
14036                    pw.print(", restore limit ");
14037                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14038                    pw.print(" kB");
14039                    if (ActivityManager.isLowRamDeviceStatic()) {
14040                        pw.print(" (low-ram)");
14041                    }
14042                    if (ActivityManager.isHighEndGfx()) {
14043                        pw.print(" (high-end-gfx)");
14044                    }
14045                    pw.println();
14046                } else {
14047                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14048                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14049                    pw.println(voltile);
14050                    pw.print("tuning,");
14051                    pw.print(ActivityManager.staticGetMemoryClass());
14052                    pw.print(',');
14053                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14054                    pw.print(',');
14055                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14056                    if (ActivityManager.isLowRamDeviceStatic()) {
14057                        pw.print(",low-ram");
14058                    }
14059                    if (ActivityManager.isHighEndGfx()) {
14060                        pw.print(",high-end-gfx");
14061                    }
14062                    pw.println();
14063                }
14064            }
14065        }
14066    }
14067
14068    /**
14069     * Searches array of arguments for the specified string
14070     * @param args array of argument strings
14071     * @param value value to search for
14072     * @return true if the value is contained in the array
14073     */
14074    private static boolean scanArgs(String[] args, String value) {
14075        if (args != null) {
14076            for (String arg : args) {
14077                if (value.equals(arg)) {
14078                    return true;
14079                }
14080            }
14081        }
14082        return false;
14083    }
14084
14085    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14086            ContentProviderRecord cpr, boolean always) {
14087        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14088
14089        if (!inLaunching || always) {
14090            synchronized (cpr) {
14091                cpr.launchingApp = null;
14092                cpr.notifyAll();
14093            }
14094            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14095            String names[] = cpr.info.authority.split(";");
14096            for (int j = 0; j < names.length; j++) {
14097                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14098            }
14099        }
14100
14101        for (int i=0; i<cpr.connections.size(); i++) {
14102            ContentProviderConnection conn = cpr.connections.get(i);
14103            if (conn.waiting) {
14104                // If this connection is waiting for the provider, then we don't
14105                // need to mess with its process unless we are always removing
14106                // or for some reason the provider is not currently launching.
14107                if (inLaunching && !always) {
14108                    continue;
14109                }
14110            }
14111            ProcessRecord capp = conn.client;
14112            conn.dead = true;
14113            if (conn.stableCount > 0) {
14114                if (!capp.persistent && capp.thread != null
14115                        && capp.pid != 0
14116                        && capp.pid != MY_PID) {
14117                    capp.kill("depends on provider "
14118                            + cpr.name.flattenToShortString()
14119                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14120                }
14121            } else if (capp.thread != null && conn.provider.provider != null) {
14122                try {
14123                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14124                } catch (RemoteException e) {
14125                }
14126                // In the protocol here, we don't expect the client to correctly
14127                // clean up this connection, we'll just remove it.
14128                cpr.connections.remove(i);
14129                conn.client.conProviders.remove(conn);
14130            }
14131        }
14132
14133        if (inLaunching && always) {
14134            mLaunchingProviders.remove(cpr);
14135        }
14136        return inLaunching;
14137    }
14138
14139    /**
14140     * Main code for cleaning up a process when it has gone away.  This is
14141     * called both as a result of the process dying, or directly when stopping
14142     * a process when running in single process mode.
14143     */
14144    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14145            boolean restarting, boolean allowRestart, int index) {
14146        if (index >= 0) {
14147            removeLruProcessLocked(app);
14148            ProcessList.remove(app.pid);
14149        }
14150
14151        mProcessesToGc.remove(app);
14152        mPendingPssProcesses.remove(app);
14153
14154        // Dismiss any open dialogs.
14155        if (app.crashDialog != null && !app.forceCrashReport) {
14156            app.crashDialog.dismiss();
14157            app.crashDialog = null;
14158        }
14159        if (app.anrDialog != null) {
14160            app.anrDialog.dismiss();
14161            app.anrDialog = null;
14162        }
14163        if (app.waitDialog != null) {
14164            app.waitDialog.dismiss();
14165            app.waitDialog = null;
14166        }
14167
14168        app.crashing = false;
14169        app.notResponding = false;
14170
14171        app.resetPackageList(mProcessStats);
14172        app.unlinkDeathRecipient();
14173        app.makeInactive(mProcessStats);
14174        app.waitingToKill = null;
14175        app.forcingToForeground = null;
14176        updateProcessForegroundLocked(app, false, false);
14177        app.foregroundActivities = false;
14178        app.hasShownUi = false;
14179        app.treatLikeActivity = false;
14180        app.hasAboveClient = false;
14181        app.hasClientActivities = false;
14182
14183        mServices.killServicesLocked(app, allowRestart);
14184
14185        boolean restart = false;
14186
14187        // Remove published content providers.
14188        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14189            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14190            final boolean always = app.bad || !allowRestart;
14191            if (removeDyingProviderLocked(app, cpr, always) || always) {
14192                // We left the provider in the launching list, need to
14193                // restart it.
14194                restart = true;
14195            }
14196
14197            cpr.provider = null;
14198            cpr.proc = null;
14199        }
14200        app.pubProviders.clear();
14201
14202        // Take care of any launching providers waiting for this process.
14203        if (checkAppInLaunchingProvidersLocked(app, false)) {
14204            restart = true;
14205        }
14206
14207        // Unregister from connected content providers.
14208        if (!app.conProviders.isEmpty()) {
14209            for (int i=0; i<app.conProviders.size(); i++) {
14210                ContentProviderConnection conn = app.conProviders.get(i);
14211                conn.provider.connections.remove(conn);
14212            }
14213            app.conProviders.clear();
14214        }
14215
14216        // At this point there may be remaining entries in mLaunchingProviders
14217        // where we were the only one waiting, so they are no longer of use.
14218        // Look for these and clean up if found.
14219        // XXX Commented out for now.  Trying to figure out a way to reproduce
14220        // the actual situation to identify what is actually going on.
14221        if (false) {
14222            for (int i=0; i<mLaunchingProviders.size(); i++) {
14223                ContentProviderRecord cpr = (ContentProviderRecord)
14224                        mLaunchingProviders.get(i);
14225                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14226                    synchronized (cpr) {
14227                        cpr.launchingApp = null;
14228                        cpr.notifyAll();
14229                    }
14230                }
14231            }
14232        }
14233
14234        skipCurrentReceiverLocked(app);
14235
14236        // Unregister any receivers.
14237        for (int i=app.receivers.size()-1; i>=0; i--) {
14238            removeReceiverLocked(app.receivers.valueAt(i));
14239        }
14240        app.receivers.clear();
14241
14242        // If the app is undergoing backup, tell the backup manager about it
14243        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14244            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14245                    + mBackupTarget.appInfo + " died during backup");
14246            try {
14247                IBackupManager bm = IBackupManager.Stub.asInterface(
14248                        ServiceManager.getService(Context.BACKUP_SERVICE));
14249                bm.agentDisconnected(app.info.packageName);
14250            } catch (RemoteException e) {
14251                // can't happen; backup manager is local
14252            }
14253        }
14254
14255        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14256            ProcessChangeItem item = mPendingProcessChanges.get(i);
14257            if (item.pid == app.pid) {
14258                mPendingProcessChanges.remove(i);
14259                mAvailProcessChanges.add(item);
14260            }
14261        }
14262        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14263
14264        // If the caller is restarting this app, then leave it in its
14265        // current lists and let the caller take care of it.
14266        if (restarting) {
14267            return;
14268        }
14269
14270        if (!app.persistent || app.isolated) {
14271            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14272                    "Removing non-persistent process during cleanup: " + app);
14273            mProcessNames.remove(app.processName, app.uid);
14274            mIsolatedProcesses.remove(app.uid);
14275            if (mHeavyWeightProcess == app) {
14276                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14277                        mHeavyWeightProcess.userId, 0));
14278                mHeavyWeightProcess = null;
14279            }
14280        } else if (!app.removed) {
14281            // This app is persistent, so we need to keep its record around.
14282            // If it is not already on the pending app list, add it there
14283            // and start a new process for it.
14284            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14285                mPersistentStartingProcesses.add(app);
14286                restart = true;
14287            }
14288        }
14289        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14290                "Clean-up removing on hold: " + app);
14291        mProcessesOnHold.remove(app);
14292
14293        if (app == mHomeProcess) {
14294            mHomeProcess = null;
14295        }
14296        if (app == mPreviousProcess) {
14297            mPreviousProcess = null;
14298        }
14299
14300        if (restart && !app.isolated) {
14301            // We have components that still need to be running in the
14302            // process, so re-launch it.
14303            mProcessNames.put(app.processName, app.uid, app);
14304            startProcessLocked(app, "restart", app.processName);
14305        } else if (app.pid > 0 && app.pid != MY_PID) {
14306            // Goodbye!
14307            boolean removed;
14308            synchronized (mPidsSelfLocked) {
14309                mPidsSelfLocked.remove(app.pid);
14310                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14311            }
14312            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14313            if (app.isolated) {
14314                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14315            }
14316            app.setPid(0);
14317        }
14318    }
14319
14320    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14321        // Look through the content providers we are waiting to have launched,
14322        // and if any run in this process then either schedule a restart of
14323        // the process or kill the client waiting for it if this process has
14324        // gone bad.
14325        int NL = mLaunchingProviders.size();
14326        boolean restart = false;
14327        for (int i=0; i<NL; i++) {
14328            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14329            if (cpr.launchingApp == app) {
14330                if (!alwaysBad && !app.bad) {
14331                    restart = true;
14332                } else {
14333                    removeDyingProviderLocked(app, cpr, true);
14334                    // cpr should have been removed from mLaunchingProviders
14335                    NL = mLaunchingProviders.size();
14336                    i--;
14337                }
14338            }
14339        }
14340        return restart;
14341    }
14342
14343    // =========================================================
14344    // SERVICES
14345    // =========================================================
14346
14347    @Override
14348    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14349            int flags) {
14350        enforceNotIsolatedCaller("getServices");
14351        synchronized (this) {
14352            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14353        }
14354    }
14355
14356    @Override
14357    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14358        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14359        synchronized (this) {
14360            return mServices.getRunningServiceControlPanelLocked(name);
14361        }
14362    }
14363
14364    @Override
14365    public ComponentName startService(IApplicationThread caller, Intent service,
14366            String resolvedType, int userId) {
14367        enforceNotIsolatedCaller("startService");
14368        // Refuse possible leaked file descriptors
14369        if (service != null && service.hasFileDescriptors() == true) {
14370            throw new IllegalArgumentException("File descriptors passed in Intent");
14371        }
14372
14373        if (DEBUG_SERVICE)
14374            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14375        synchronized(this) {
14376            final int callingPid = Binder.getCallingPid();
14377            final int callingUid = Binder.getCallingUid();
14378            final long origId = Binder.clearCallingIdentity();
14379            ComponentName res = mServices.startServiceLocked(caller, service,
14380                    resolvedType, callingPid, callingUid, userId);
14381            Binder.restoreCallingIdentity(origId);
14382            return res;
14383        }
14384    }
14385
14386    ComponentName startServiceInPackage(int uid,
14387            Intent service, String resolvedType, int userId) {
14388        synchronized(this) {
14389            if (DEBUG_SERVICE)
14390                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14391            final long origId = Binder.clearCallingIdentity();
14392            ComponentName res = mServices.startServiceLocked(null, service,
14393                    resolvedType, -1, uid, userId);
14394            Binder.restoreCallingIdentity(origId);
14395            return res;
14396        }
14397    }
14398
14399    @Override
14400    public int stopService(IApplicationThread caller, Intent service,
14401            String resolvedType, int userId) {
14402        enforceNotIsolatedCaller("stopService");
14403        // Refuse possible leaked file descriptors
14404        if (service != null && service.hasFileDescriptors() == true) {
14405            throw new IllegalArgumentException("File descriptors passed in Intent");
14406        }
14407
14408        synchronized(this) {
14409            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14410        }
14411    }
14412
14413    @Override
14414    public IBinder peekService(Intent service, String resolvedType) {
14415        enforceNotIsolatedCaller("peekService");
14416        // Refuse possible leaked file descriptors
14417        if (service != null && service.hasFileDescriptors() == true) {
14418            throw new IllegalArgumentException("File descriptors passed in Intent");
14419        }
14420        synchronized(this) {
14421            return mServices.peekServiceLocked(service, resolvedType);
14422        }
14423    }
14424
14425    @Override
14426    public boolean stopServiceToken(ComponentName className, IBinder token,
14427            int startId) {
14428        synchronized(this) {
14429            return mServices.stopServiceTokenLocked(className, token, startId);
14430        }
14431    }
14432
14433    @Override
14434    public void setServiceForeground(ComponentName className, IBinder token,
14435            int id, Notification notification, boolean removeNotification) {
14436        synchronized(this) {
14437            mServices.setServiceForegroundLocked(className, token, id, notification,
14438                    removeNotification);
14439        }
14440    }
14441
14442    @Override
14443    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14444            boolean requireFull, String name, String callerPackage) {
14445        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14446                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14447    }
14448
14449    int unsafeConvertIncomingUser(int userId) {
14450        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14451                ? mCurrentUserId : userId;
14452    }
14453
14454    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14455            int allowMode, String name, String callerPackage) {
14456        final int callingUserId = UserHandle.getUserId(callingUid);
14457        if (callingUserId == userId) {
14458            return userId;
14459        }
14460
14461        // Note that we may be accessing mCurrentUserId outside of a lock...
14462        // shouldn't be a big deal, if this is being called outside
14463        // of a locked context there is intrinsically a race with
14464        // the value the caller will receive and someone else changing it.
14465        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14466        // we will switch to the calling user if access to the current user fails.
14467        int targetUserId = unsafeConvertIncomingUser(userId);
14468
14469        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14470            final boolean allow;
14471            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14472                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14473                // If the caller has this permission, they always pass go.  And collect $200.
14474                allow = true;
14475            } else if (allowMode == ALLOW_FULL_ONLY) {
14476                // We require full access, sucks to be you.
14477                allow = false;
14478            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14479                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14480                // If the caller does not have either permission, they are always doomed.
14481                allow = false;
14482            } else if (allowMode == ALLOW_NON_FULL) {
14483                // We are blanket allowing non-full access, you lucky caller!
14484                allow = true;
14485            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14486                // We may or may not allow this depending on whether the two users are
14487                // in the same profile.
14488                synchronized (mUserProfileGroupIdsSelfLocked) {
14489                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14490                            UserInfo.NO_PROFILE_GROUP_ID);
14491                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14492                            UserInfo.NO_PROFILE_GROUP_ID);
14493                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14494                            && callingProfile == targetProfile;
14495                }
14496            } else {
14497                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14498            }
14499            if (!allow) {
14500                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14501                    // In this case, they would like to just execute as their
14502                    // owner user instead of failing.
14503                    targetUserId = callingUserId;
14504                } else {
14505                    StringBuilder builder = new StringBuilder(128);
14506                    builder.append("Permission Denial: ");
14507                    builder.append(name);
14508                    if (callerPackage != null) {
14509                        builder.append(" from ");
14510                        builder.append(callerPackage);
14511                    }
14512                    builder.append(" asks to run as user ");
14513                    builder.append(userId);
14514                    builder.append(" but is calling from user ");
14515                    builder.append(UserHandle.getUserId(callingUid));
14516                    builder.append("; this requires ");
14517                    builder.append(INTERACT_ACROSS_USERS_FULL);
14518                    if (allowMode != ALLOW_FULL_ONLY) {
14519                        builder.append(" or ");
14520                        builder.append(INTERACT_ACROSS_USERS);
14521                    }
14522                    String msg = builder.toString();
14523                    Slog.w(TAG, msg);
14524                    throw new SecurityException(msg);
14525                }
14526            }
14527        }
14528        if (!allowAll && targetUserId < 0) {
14529            throw new IllegalArgumentException(
14530                    "Call does not support special user #" + targetUserId);
14531        }
14532        return targetUserId;
14533    }
14534
14535    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14536            String className, int flags) {
14537        boolean result = false;
14538        // For apps that don't have pre-defined UIDs, check for permission
14539        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14540            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14541                if (ActivityManager.checkUidPermission(
14542                        INTERACT_ACROSS_USERS,
14543                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14544                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14545                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14546                            + " requests FLAG_SINGLE_USER, but app does not hold "
14547                            + INTERACT_ACROSS_USERS;
14548                    Slog.w(TAG, msg);
14549                    throw new SecurityException(msg);
14550                }
14551                // Permission passed
14552                result = true;
14553            }
14554        } else if ("system".equals(componentProcessName)) {
14555            result = true;
14556        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14557                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14558            // Phone app is allowed to export singleuser providers.
14559            result = true;
14560        } else {
14561            // App with pre-defined UID, check if it's a persistent app
14562            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14563        }
14564        if (DEBUG_MU) {
14565            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14566                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14567        }
14568        return result;
14569    }
14570
14571    /**
14572     * Checks to see if the caller is in the same app as the singleton
14573     * component, or the component is in a special app. It allows special apps
14574     * to export singleton components but prevents exporting singleton
14575     * components for regular apps.
14576     */
14577    boolean isValidSingletonCall(int callingUid, int componentUid) {
14578        int componentAppId = UserHandle.getAppId(componentUid);
14579        return UserHandle.isSameApp(callingUid, componentUid)
14580                || componentAppId == Process.SYSTEM_UID
14581                || componentAppId == Process.PHONE_UID
14582                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14583                        == PackageManager.PERMISSION_GRANTED;
14584    }
14585
14586    public int bindService(IApplicationThread caller, IBinder token,
14587            Intent service, String resolvedType,
14588            IServiceConnection connection, int flags, int userId) {
14589        enforceNotIsolatedCaller("bindService");
14590        // Refuse possible leaked file descriptors
14591        if (service != null && service.hasFileDescriptors() == true) {
14592            throw new IllegalArgumentException("File descriptors passed in Intent");
14593        }
14594
14595        synchronized(this) {
14596            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14597                    connection, flags, userId);
14598        }
14599    }
14600
14601    public boolean unbindService(IServiceConnection connection) {
14602        synchronized (this) {
14603            return mServices.unbindServiceLocked(connection);
14604        }
14605    }
14606
14607    public void publishService(IBinder token, Intent intent, IBinder service) {
14608        // Refuse possible leaked file descriptors
14609        if (intent != null && intent.hasFileDescriptors() == true) {
14610            throw new IllegalArgumentException("File descriptors passed in Intent");
14611        }
14612
14613        synchronized(this) {
14614            if (!(token instanceof ServiceRecord)) {
14615                throw new IllegalArgumentException("Invalid service token");
14616            }
14617            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14618        }
14619    }
14620
14621    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14622        // Refuse possible leaked file descriptors
14623        if (intent != null && intent.hasFileDescriptors() == true) {
14624            throw new IllegalArgumentException("File descriptors passed in Intent");
14625        }
14626
14627        synchronized(this) {
14628            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14629        }
14630    }
14631
14632    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14633        synchronized(this) {
14634            if (!(token instanceof ServiceRecord)) {
14635                throw new IllegalArgumentException("Invalid service token");
14636            }
14637            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14638        }
14639    }
14640
14641    // =========================================================
14642    // BACKUP AND RESTORE
14643    // =========================================================
14644
14645    // Cause the target app to be launched if necessary and its backup agent
14646    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14647    // activity manager to announce its creation.
14648    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14649        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14650        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14651
14652        synchronized(this) {
14653            // !!! TODO: currently no check here that we're already bound
14654            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14655            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14656            synchronized (stats) {
14657                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14658            }
14659
14660            // Backup agent is now in use, its package can't be stopped.
14661            try {
14662                AppGlobals.getPackageManager().setPackageStoppedState(
14663                        app.packageName, false, UserHandle.getUserId(app.uid));
14664            } catch (RemoteException e) {
14665            } catch (IllegalArgumentException e) {
14666                Slog.w(TAG, "Failed trying to unstop package "
14667                        + app.packageName + ": " + e);
14668            }
14669
14670            BackupRecord r = new BackupRecord(ss, app, backupMode);
14671            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14672                    ? new ComponentName(app.packageName, app.backupAgentName)
14673                    : new ComponentName("android", "FullBackupAgent");
14674            // startProcessLocked() returns existing proc's record if it's already running
14675            ProcessRecord proc = startProcessLocked(app.processName, app,
14676                    false, 0, "backup", hostingName, false, false, false);
14677            if (proc == null) {
14678                Slog.e(TAG, "Unable to start backup agent process " + r);
14679                return false;
14680            }
14681
14682            r.app = proc;
14683            mBackupTarget = r;
14684            mBackupAppName = app.packageName;
14685
14686            // Try not to kill the process during backup
14687            updateOomAdjLocked(proc);
14688
14689            // If the process is already attached, schedule the creation of the backup agent now.
14690            // If it is not yet live, this will be done when it attaches to the framework.
14691            if (proc.thread != null) {
14692                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14693                try {
14694                    proc.thread.scheduleCreateBackupAgent(app,
14695                            compatibilityInfoForPackageLocked(app), backupMode);
14696                } catch (RemoteException e) {
14697                    // Will time out on the backup manager side
14698                }
14699            } else {
14700                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14701            }
14702            // Invariants: at this point, the target app process exists and the application
14703            // is either already running or in the process of coming up.  mBackupTarget and
14704            // mBackupAppName describe the app, so that when it binds back to the AM we
14705            // know that it's scheduled for a backup-agent operation.
14706        }
14707
14708        return true;
14709    }
14710
14711    @Override
14712    public void clearPendingBackup() {
14713        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14714        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14715
14716        synchronized (this) {
14717            mBackupTarget = null;
14718            mBackupAppName = null;
14719        }
14720    }
14721
14722    // A backup agent has just come up
14723    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14724        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14725                + " = " + agent);
14726
14727        synchronized(this) {
14728            if (!agentPackageName.equals(mBackupAppName)) {
14729                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14730                return;
14731            }
14732        }
14733
14734        long oldIdent = Binder.clearCallingIdentity();
14735        try {
14736            IBackupManager bm = IBackupManager.Stub.asInterface(
14737                    ServiceManager.getService(Context.BACKUP_SERVICE));
14738            bm.agentConnected(agentPackageName, agent);
14739        } catch (RemoteException e) {
14740            // can't happen; the backup manager service is local
14741        } catch (Exception e) {
14742            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14743            e.printStackTrace();
14744        } finally {
14745            Binder.restoreCallingIdentity(oldIdent);
14746        }
14747    }
14748
14749    // done with this agent
14750    public void unbindBackupAgent(ApplicationInfo appInfo) {
14751        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14752        if (appInfo == null) {
14753            Slog.w(TAG, "unbind backup agent for null app");
14754            return;
14755        }
14756
14757        synchronized(this) {
14758            try {
14759                if (mBackupAppName == null) {
14760                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14761                    return;
14762                }
14763
14764                if (!mBackupAppName.equals(appInfo.packageName)) {
14765                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14766                    return;
14767                }
14768
14769                // Not backing this app up any more; reset its OOM adjustment
14770                final ProcessRecord proc = mBackupTarget.app;
14771                updateOomAdjLocked(proc);
14772
14773                // If the app crashed during backup, 'thread' will be null here
14774                if (proc.thread != null) {
14775                    try {
14776                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14777                                compatibilityInfoForPackageLocked(appInfo));
14778                    } catch (Exception e) {
14779                        Slog.e(TAG, "Exception when unbinding backup agent:");
14780                        e.printStackTrace();
14781                    }
14782                }
14783            } finally {
14784                mBackupTarget = null;
14785                mBackupAppName = null;
14786            }
14787        }
14788    }
14789    // =========================================================
14790    // BROADCASTS
14791    // =========================================================
14792
14793    private final List getStickiesLocked(String action, IntentFilter filter,
14794            List cur, int userId) {
14795        final ContentResolver resolver = mContext.getContentResolver();
14796        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14797        if (stickies == null) {
14798            return cur;
14799        }
14800        final ArrayList<Intent> list = stickies.get(action);
14801        if (list == null) {
14802            return cur;
14803        }
14804        int N = list.size();
14805        for (int i=0; i<N; i++) {
14806            Intent intent = list.get(i);
14807            if (filter.match(resolver, intent, true, TAG) >= 0) {
14808                if (cur == null) {
14809                    cur = new ArrayList<Intent>();
14810                }
14811                cur.add(intent);
14812            }
14813        }
14814        return cur;
14815    }
14816
14817    boolean isPendingBroadcastProcessLocked(int pid) {
14818        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14819                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14820    }
14821
14822    void skipPendingBroadcastLocked(int pid) {
14823            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14824            for (BroadcastQueue queue : mBroadcastQueues) {
14825                queue.skipPendingBroadcastLocked(pid);
14826            }
14827    }
14828
14829    // The app just attached; send any pending broadcasts that it should receive
14830    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14831        boolean didSomething = false;
14832        for (BroadcastQueue queue : mBroadcastQueues) {
14833            didSomething |= queue.sendPendingBroadcastsLocked(app);
14834        }
14835        return didSomething;
14836    }
14837
14838    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14839            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14840        enforceNotIsolatedCaller("registerReceiver");
14841        int callingUid;
14842        int callingPid;
14843        synchronized(this) {
14844            ProcessRecord callerApp = null;
14845            if (caller != null) {
14846                callerApp = getRecordForAppLocked(caller);
14847                if (callerApp == null) {
14848                    throw new SecurityException(
14849                            "Unable to find app for caller " + caller
14850                            + " (pid=" + Binder.getCallingPid()
14851                            + ") when registering receiver " + receiver);
14852                }
14853                if (callerApp.info.uid != Process.SYSTEM_UID &&
14854                        !callerApp.pkgList.containsKey(callerPackage) &&
14855                        !"android".equals(callerPackage)) {
14856                    throw new SecurityException("Given caller package " + callerPackage
14857                            + " is not running in process " + callerApp);
14858                }
14859                callingUid = callerApp.info.uid;
14860                callingPid = callerApp.pid;
14861            } else {
14862                callerPackage = null;
14863                callingUid = Binder.getCallingUid();
14864                callingPid = Binder.getCallingPid();
14865            }
14866
14867            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14868                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14869
14870            List allSticky = null;
14871
14872            // Look for any matching sticky broadcasts...
14873            Iterator actions = filter.actionsIterator();
14874            if (actions != null) {
14875                while (actions.hasNext()) {
14876                    String action = (String)actions.next();
14877                    allSticky = getStickiesLocked(action, filter, allSticky,
14878                            UserHandle.USER_ALL);
14879                    allSticky = getStickiesLocked(action, filter, allSticky,
14880                            UserHandle.getUserId(callingUid));
14881                }
14882            } else {
14883                allSticky = getStickiesLocked(null, filter, allSticky,
14884                        UserHandle.USER_ALL);
14885                allSticky = getStickiesLocked(null, filter, allSticky,
14886                        UserHandle.getUserId(callingUid));
14887            }
14888
14889            // The first sticky in the list is returned directly back to
14890            // the client.
14891            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14892
14893            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14894                    + ": " + sticky);
14895
14896            if (receiver == null) {
14897                return sticky;
14898            }
14899
14900            ReceiverList rl
14901                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14902            if (rl == null) {
14903                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14904                        userId, receiver);
14905                if (rl.app != null) {
14906                    rl.app.receivers.add(rl);
14907                } else {
14908                    try {
14909                        receiver.asBinder().linkToDeath(rl, 0);
14910                    } catch (RemoteException e) {
14911                        return sticky;
14912                    }
14913                    rl.linkedToDeath = true;
14914                }
14915                mRegisteredReceivers.put(receiver.asBinder(), rl);
14916            } else if (rl.uid != callingUid) {
14917                throw new IllegalArgumentException(
14918                        "Receiver requested to register for uid " + callingUid
14919                        + " was previously registered for uid " + rl.uid);
14920            } else if (rl.pid != callingPid) {
14921                throw new IllegalArgumentException(
14922                        "Receiver requested to register for pid " + callingPid
14923                        + " was previously registered for pid " + rl.pid);
14924            } else if (rl.userId != userId) {
14925                throw new IllegalArgumentException(
14926                        "Receiver requested to register for user " + userId
14927                        + " was previously registered for user " + rl.userId);
14928            }
14929            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14930                    permission, callingUid, userId);
14931            rl.add(bf);
14932            if (!bf.debugCheck()) {
14933                Slog.w(TAG, "==> For Dynamic broadast");
14934            }
14935            mReceiverResolver.addFilter(bf);
14936
14937            // Enqueue broadcasts for all existing stickies that match
14938            // this filter.
14939            if (allSticky != null) {
14940                ArrayList receivers = new ArrayList();
14941                receivers.add(bf);
14942
14943                int N = allSticky.size();
14944                for (int i=0; i<N; i++) {
14945                    Intent intent = (Intent)allSticky.get(i);
14946                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14947                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14948                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14949                            null, null, false, true, true, -1);
14950                    queue.enqueueParallelBroadcastLocked(r);
14951                    queue.scheduleBroadcastsLocked();
14952                }
14953            }
14954
14955            return sticky;
14956        }
14957    }
14958
14959    public void unregisterReceiver(IIntentReceiver receiver) {
14960        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14961
14962        final long origId = Binder.clearCallingIdentity();
14963        try {
14964            boolean doTrim = false;
14965
14966            synchronized(this) {
14967                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14968                if (rl != null) {
14969                    if (rl.curBroadcast != null) {
14970                        BroadcastRecord r = rl.curBroadcast;
14971                        final boolean doNext = finishReceiverLocked(
14972                                receiver.asBinder(), r.resultCode, r.resultData,
14973                                r.resultExtras, r.resultAbort);
14974                        if (doNext) {
14975                            doTrim = true;
14976                            r.queue.processNextBroadcast(false);
14977                        }
14978                    }
14979
14980                    if (rl.app != null) {
14981                        rl.app.receivers.remove(rl);
14982                    }
14983                    removeReceiverLocked(rl);
14984                    if (rl.linkedToDeath) {
14985                        rl.linkedToDeath = false;
14986                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14987                    }
14988                }
14989            }
14990
14991            // If we actually concluded any broadcasts, we might now be able
14992            // to trim the recipients' apps from our working set
14993            if (doTrim) {
14994                trimApplications();
14995                return;
14996            }
14997
14998        } finally {
14999            Binder.restoreCallingIdentity(origId);
15000        }
15001    }
15002
15003    void removeReceiverLocked(ReceiverList rl) {
15004        mRegisteredReceivers.remove(rl.receiver.asBinder());
15005        int N = rl.size();
15006        for (int i=0; i<N; i++) {
15007            mReceiverResolver.removeFilter(rl.get(i));
15008        }
15009    }
15010
15011    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15012        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15013            ProcessRecord r = mLruProcesses.get(i);
15014            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15015                try {
15016                    r.thread.dispatchPackageBroadcast(cmd, packages);
15017                } catch (RemoteException ex) {
15018                }
15019            }
15020        }
15021    }
15022
15023    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15024            int[] users) {
15025        List<ResolveInfo> receivers = null;
15026        try {
15027            HashSet<ComponentName> singleUserReceivers = null;
15028            boolean scannedFirstReceivers = false;
15029            for (int user : users) {
15030                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15031                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15032                if (user != 0 && newReceivers != null) {
15033                    // If this is not the primary user, we need to check for
15034                    // any receivers that should be filtered out.
15035                    for (int i=0; i<newReceivers.size(); i++) {
15036                        ResolveInfo ri = newReceivers.get(i);
15037                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15038                            newReceivers.remove(i);
15039                            i--;
15040                        }
15041                    }
15042                }
15043                if (newReceivers != null && newReceivers.size() == 0) {
15044                    newReceivers = null;
15045                }
15046                if (receivers == null) {
15047                    receivers = newReceivers;
15048                } else if (newReceivers != null) {
15049                    // We need to concatenate the additional receivers
15050                    // found with what we have do far.  This would be easy,
15051                    // but we also need to de-dup any receivers that are
15052                    // singleUser.
15053                    if (!scannedFirstReceivers) {
15054                        // Collect any single user receivers we had already retrieved.
15055                        scannedFirstReceivers = true;
15056                        for (int i=0; i<receivers.size(); i++) {
15057                            ResolveInfo ri = receivers.get(i);
15058                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15059                                ComponentName cn = new ComponentName(
15060                                        ri.activityInfo.packageName, ri.activityInfo.name);
15061                                if (singleUserReceivers == null) {
15062                                    singleUserReceivers = new HashSet<ComponentName>();
15063                                }
15064                                singleUserReceivers.add(cn);
15065                            }
15066                        }
15067                    }
15068                    // Add the new results to the existing results, tracking
15069                    // and de-dupping single user receivers.
15070                    for (int i=0; i<newReceivers.size(); i++) {
15071                        ResolveInfo ri = newReceivers.get(i);
15072                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15073                            ComponentName cn = new ComponentName(
15074                                    ri.activityInfo.packageName, ri.activityInfo.name);
15075                            if (singleUserReceivers == null) {
15076                                singleUserReceivers = new HashSet<ComponentName>();
15077                            }
15078                            if (!singleUserReceivers.contains(cn)) {
15079                                singleUserReceivers.add(cn);
15080                                receivers.add(ri);
15081                            }
15082                        } else {
15083                            receivers.add(ri);
15084                        }
15085                    }
15086                }
15087            }
15088        } catch (RemoteException ex) {
15089            // pm is in same process, this will never happen.
15090        }
15091        return receivers;
15092    }
15093
15094    private final int broadcastIntentLocked(ProcessRecord callerApp,
15095            String callerPackage, Intent intent, String resolvedType,
15096            IIntentReceiver resultTo, int resultCode, String resultData,
15097            Bundle map, String requiredPermission, int appOp,
15098            boolean ordered, boolean sticky, int callingPid, int callingUid,
15099            int userId) {
15100        intent = new Intent(intent);
15101
15102        // By default broadcasts do not go to stopped apps.
15103        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15104
15105        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15106            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15107            + " ordered=" + ordered + " userid=" + userId);
15108        if ((resultTo != null) && !ordered) {
15109            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15110        }
15111
15112        userId = handleIncomingUser(callingPid, callingUid, userId,
15113                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15114
15115        // Make sure that the user who is receiving this broadcast is started.
15116        // If not, we will just skip it.
15117
15118
15119        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15120            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15121                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15122                Slog.w(TAG, "Skipping broadcast of " + intent
15123                        + ": user " + userId + " is stopped");
15124                return ActivityManager.BROADCAST_SUCCESS;
15125            }
15126        }
15127
15128        /*
15129         * Prevent non-system code (defined here to be non-persistent
15130         * processes) from sending protected broadcasts.
15131         */
15132        int callingAppId = UserHandle.getAppId(callingUid);
15133        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15134            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15135            || callingAppId == Process.NFC_UID || callingUid == 0) {
15136            // Always okay.
15137        } else if (callerApp == null || !callerApp.persistent) {
15138            try {
15139                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15140                        intent.getAction())) {
15141                    String msg = "Permission Denial: not allowed to send broadcast "
15142                            + intent.getAction() + " from pid="
15143                            + callingPid + ", uid=" + callingUid;
15144                    Slog.w(TAG, msg);
15145                    throw new SecurityException(msg);
15146                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15147                    // Special case for compatibility: we don't want apps to send this,
15148                    // but historically it has not been protected and apps may be using it
15149                    // to poke their own app widget.  So, instead of making it protected,
15150                    // just limit it to the caller.
15151                    if (callerApp == null) {
15152                        String msg = "Permission Denial: not allowed to send broadcast "
15153                                + intent.getAction() + " from unknown caller.";
15154                        Slog.w(TAG, msg);
15155                        throw new SecurityException(msg);
15156                    } else if (intent.getComponent() != null) {
15157                        // They are good enough to send to an explicit component...  verify
15158                        // it is being sent to the calling app.
15159                        if (!intent.getComponent().getPackageName().equals(
15160                                callerApp.info.packageName)) {
15161                            String msg = "Permission Denial: not allowed to send broadcast "
15162                                    + intent.getAction() + " to "
15163                                    + intent.getComponent().getPackageName() + " from "
15164                                    + callerApp.info.packageName;
15165                            Slog.w(TAG, msg);
15166                            throw new SecurityException(msg);
15167                        }
15168                    } else {
15169                        // Limit broadcast to their own package.
15170                        intent.setPackage(callerApp.info.packageName);
15171                    }
15172                }
15173            } catch (RemoteException e) {
15174                Slog.w(TAG, "Remote exception", e);
15175                return ActivityManager.BROADCAST_SUCCESS;
15176            }
15177        }
15178
15179        // Handle special intents: if this broadcast is from the package
15180        // manager about a package being removed, we need to remove all of
15181        // its activities from the history stack.
15182        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15183                intent.getAction());
15184        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15185                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15186                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15187                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15188                || uidRemoved) {
15189            if (checkComponentPermission(
15190                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15191                    callingPid, callingUid, -1, true)
15192                    == PackageManager.PERMISSION_GRANTED) {
15193                if (uidRemoved) {
15194                    final Bundle intentExtras = intent.getExtras();
15195                    final int uid = intentExtras != null
15196                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15197                    if (uid >= 0) {
15198                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15199                        synchronized (bs) {
15200                            bs.removeUidStatsLocked(uid);
15201                        }
15202                        mAppOpsService.uidRemoved(uid);
15203                    }
15204                } else {
15205                    // If resources are unavailable just force stop all
15206                    // those packages and flush the attribute cache as well.
15207                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15208                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15209                        if (list != null && (list.length > 0)) {
15210                            for (String pkg : list) {
15211                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15212                                        "storage unmount");
15213                            }
15214                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15215                            sendPackageBroadcastLocked(
15216                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15217                        }
15218                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15219                            intent.getAction())) {
15220                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15221                    } else {
15222                        Uri data = intent.getData();
15223                        String ssp;
15224                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15225                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15226                                    intent.getAction());
15227                            boolean fullUninstall = removed &&
15228                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15229                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15230                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15231                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15232                                        false, fullUninstall, userId,
15233                                        removed ? "pkg removed" : "pkg changed");
15234                            }
15235                            if (removed) {
15236                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15237                                        new String[] {ssp}, userId);
15238                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15239                                    mAppOpsService.packageRemoved(
15240                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15241
15242                                    // Remove all permissions granted from/to this package
15243                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15244                                }
15245                            }
15246                        }
15247                    }
15248                }
15249            } else {
15250                String msg = "Permission Denial: " + intent.getAction()
15251                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15252                        + ", uid=" + callingUid + ")"
15253                        + " requires "
15254                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15255                Slog.w(TAG, msg);
15256                throw new SecurityException(msg);
15257            }
15258
15259        // Special case for adding a package: by default turn on compatibility
15260        // mode.
15261        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15262            Uri data = intent.getData();
15263            String ssp;
15264            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15265                mCompatModePackages.handlePackageAddedLocked(ssp,
15266                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15267            }
15268        }
15269
15270        /*
15271         * If this is the time zone changed action, queue up a message that will reset the timezone
15272         * of all currently running processes. This message will get queued up before the broadcast
15273         * happens.
15274         */
15275        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15276            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15277        }
15278
15279        /*
15280         * If the user set the time, let all running processes know.
15281         */
15282        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15283            final int is24Hour = intent.getBooleanExtra(
15284                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15285            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15286            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15287            synchronized (stats) {
15288                stats.noteCurrentTimeChangedLocked();
15289            }
15290        }
15291
15292        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15293            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15294        }
15295
15296        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15297            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15298            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15299        }
15300
15301        // Add to the sticky list if requested.
15302        if (sticky) {
15303            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15304                    callingPid, callingUid)
15305                    != PackageManager.PERMISSION_GRANTED) {
15306                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15307                        + callingPid + ", uid=" + callingUid
15308                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15309                Slog.w(TAG, msg);
15310                throw new SecurityException(msg);
15311            }
15312            if (requiredPermission != null) {
15313                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15314                        + " and enforce permission " + requiredPermission);
15315                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15316            }
15317            if (intent.getComponent() != null) {
15318                throw new SecurityException(
15319                        "Sticky broadcasts can't target a specific component");
15320            }
15321            // We use userId directly here, since the "all" target is maintained
15322            // as a separate set of sticky broadcasts.
15323            if (userId != UserHandle.USER_ALL) {
15324                // But first, if this is not a broadcast to all users, then
15325                // make sure it doesn't conflict with an existing broadcast to
15326                // all users.
15327                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15328                        UserHandle.USER_ALL);
15329                if (stickies != null) {
15330                    ArrayList<Intent> list = stickies.get(intent.getAction());
15331                    if (list != null) {
15332                        int N = list.size();
15333                        int i;
15334                        for (i=0; i<N; i++) {
15335                            if (intent.filterEquals(list.get(i))) {
15336                                throw new IllegalArgumentException(
15337                                        "Sticky broadcast " + intent + " for user "
15338                                        + userId + " conflicts with existing global broadcast");
15339                            }
15340                        }
15341                    }
15342                }
15343            }
15344            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15345            if (stickies == null) {
15346                stickies = new ArrayMap<String, ArrayList<Intent>>();
15347                mStickyBroadcasts.put(userId, stickies);
15348            }
15349            ArrayList<Intent> list = stickies.get(intent.getAction());
15350            if (list == null) {
15351                list = new ArrayList<Intent>();
15352                stickies.put(intent.getAction(), list);
15353            }
15354            int N = list.size();
15355            int i;
15356            for (i=0; i<N; i++) {
15357                if (intent.filterEquals(list.get(i))) {
15358                    // This sticky already exists, replace it.
15359                    list.set(i, new Intent(intent));
15360                    break;
15361                }
15362            }
15363            if (i >= N) {
15364                list.add(new Intent(intent));
15365            }
15366        }
15367
15368        int[] users;
15369        if (userId == UserHandle.USER_ALL) {
15370            // Caller wants broadcast to go to all started users.
15371            users = mStartedUserArray;
15372        } else {
15373            // Caller wants broadcast to go to one specific user.
15374            users = new int[] {userId};
15375        }
15376
15377        // Figure out who all will receive this broadcast.
15378        List receivers = null;
15379        List<BroadcastFilter> registeredReceivers = null;
15380        // Need to resolve the intent to interested receivers...
15381        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15382                 == 0) {
15383            receivers = collectReceiverComponents(intent, resolvedType, users);
15384        }
15385        if (intent.getComponent() == null) {
15386            registeredReceivers = mReceiverResolver.queryIntent(intent,
15387                    resolvedType, false, userId);
15388        }
15389
15390        final boolean replacePending =
15391                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15392
15393        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15394                + " replacePending=" + replacePending);
15395
15396        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15397        if (!ordered && NR > 0) {
15398            // If we are not serializing this broadcast, then send the
15399            // registered receivers separately so they don't wait for the
15400            // components to be launched.
15401            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15402            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15403                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15404                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15405                    ordered, sticky, false, userId);
15406            if (DEBUG_BROADCAST) Slog.v(
15407                    TAG, "Enqueueing parallel broadcast " + r);
15408            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15409            if (!replaced) {
15410                queue.enqueueParallelBroadcastLocked(r);
15411                queue.scheduleBroadcastsLocked();
15412            }
15413            registeredReceivers = null;
15414            NR = 0;
15415        }
15416
15417        // Merge into one list.
15418        int ir = 0;
15419        if (receivers != null) {
15420            // A special case for PACKAGE_ADDED: do not allow the package
15421            // being added to see this broadcast.  This prevents them from
15422            // using this as a back door to get run as soon as they are
15423            // installed.  Maybe in the future we want to have a special install
15424            // broadcast or such for apps, but we'd like to deliberately make
15425            // this decision.
15426            String skipPackages[] = null;
15427            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15428                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15429                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15430                Uri data = intent.getData();
15431                if (data != null) {
15432                    String pkgName = data.getSchemeSpecificPart();
15433                    if (pkgName != null) {
15434                        skipPackages = new String[] { pkgName };
15435                    }
15436                }
15437            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15438                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15439            }
15440            if (skipPackages != null && (skipPackages.length > 0)) {
15441                for (String skipPackage : skipPackages) {
15442                    if (skipPackage != null) {
15443                        int NT = receivers.size();
15444                        for (int it=0; it<NT; it++) {
15445                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15446                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15447                                receivers.remove(it);
15448                                it--;
15449                                NT--;
15450                            }
15451                        }
15452                    }
15453                }
15454            }
15455
15456            int NT = receivers != null ? receivers.size() : 0;
15457            int it = 0;
15458            ResolveInfo curt = null;
15459            BroadcastFilter curr = null;
15460            while (it < NT && ir < NR) {
15461                if (curt == null) {
15462                    curt = (ResolveInfo)receivers.get(it);
15463                }
15464                if (curr == null) {
15465                    curr = registeredReceivers.get(ir);
15466                }
15467                if (curr.getPriority() >= curt.priority) {
15468                    // Insert this broadcast record into the final list.
15469                    receivers.add(it, curr);
15470                    ir++;
15471                    curr = null;
15472                    it++;
15473                    NT++;
15474                } else {
15475                    // Skip to the next ResolveInfo in the final list.
15476                    it++;
15477                    curt = null;
15478                }
15479            }
15480        }
15481        while (ir < NR) {
15482            if (receivers == null) {
15483                receivers = new ArrayList();
15484            }
15485            receivers.add(registeredReceivers.get(ir));
15486            ir++;
15487        }
15488
15489        if ((receivers != null && receivers.size() > 0)
15490                || resultTo != null) {
15491            BroadcastQueue queue = broadcastQueueForIntent(intent);
15492            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15493                    callerPackage, callingPid, callingUid, resolvedType,
15494                    requiredPermission, appOp, receivers, resultTo, resultCode,
15495                    resultData, map, ordered, sticky, false, userId);
15496            if (DEBUG_BROADCAST) Slog.v(
15497                    TAG, "Enqueueing ordered broadcast " + r
15498                    + ": prev had " + queue.mOrderedBroadcasts.size());
15499            if (DEBUG_BROADCAST) {
15500                int seq = r.intent.getIntExtra("seq", -1);
15501                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15502            }
15503            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15504            if (!replaced) {
15505                queue.enqueueOrderedBroadcastLocked(r);
15506                queue.scheduleBroadcastsLocked();
15507            }
15508        }
15509
15510        return ActivityManager.BROADCAST_SUCCESS;
15511    }
15512
15513    final Intent verifyBroadcastLocked(Intent intent) {
15514        // Refuse possible leaked file descriptors
15515        if (intent != null && intent.hasFileDescriptors() == true) {
15516            throw new IllegalArgumentException("File descriptors passed in Intent");
15517        }
15518
15519        int flags = intent.getFlags();
15520
15521        if (!mProcessesReady) {
15522            // if the caller really truly claims to know what they're doing, go
15523            // ahead and allow the broadcast without launching any receivers
15524            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15525                intent = new Intent(intent);
15526                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15527            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15528                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15529                        + " before boot completion");
15530                throw new IllegalStateException("Cannot broadcast before boot completed");
15531            }
15532        }
15533
15534        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15535            throw new IllegalArgumentException(
15536                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15537        }
15538
15539        return intent;
15540    }
15541
15542    public final int broadcastIntent(IApplicationThread caller,
15543            Intent intent, String resolvedType, IIntentReceiver resultTo,
15544            int resultCode, String resultData, Bundle map,
15545            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15546        enforceNotIsolatedCaller("broadcastIntent");
15547        synchronized(this) {
15548            intent = verifyBroadcastLocked(intent);
15549
15550            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15551            final int callingPid = Binder.getCallingPid();
15552            final int callingUid = Binder.getCallingUid();
15553            final long origId = Binder.clearCallingIdentity();
15554            int res = broadcastIntentLocked(callerApp,
15555                    callerApp != null ? callerApp.info.packageName : null,
15556                    intent, resolvedType, resultTo,
15557                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15558                    callingPid, callingUid, userId);
15559            Binder.restoreCallingIdentity(origId);
15560            return res;
15561        }
15562    }
15563
15564    int broadcastIntentInPackage(String packageName, int uid,
15565            Intent intent, String resolvedType, IIntentReceiver resultTo,
15566            int resultCode, String resultData, Bundle map,
15567            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15568        synchronized(this) {
15569            intent = verifyBroadcastLocked(intent);
15570
15571            final long origId = Binder.clearCallingIdentity();
15572            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15573                    resultTo, resultCode, resultData, map, requiredPermission,
15574                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15575            Binder.restoreCallingIdentity(origId);
15576            return res;
15577        }
15578    }
15579
15580    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15581        // Refuse possible leaked file descriptors
15582        if (intent != null && intent.hasFileDescriptors() == true) {
15583            throw new IllegalArgumentException("File descriptors passed in Intent");
15584        }
15585
15586        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15587                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15588
15589        synchronized(this) {
15590            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15591                    != PackageManager.PERMISSION_GRANTED) {
15592                String msg = "Permission Denial: unbroadcastIntent() from pid="
15593                        + Binder.getCallingPid()
15594                        + ", uid=" + Binder.getCallingUid()
15595                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15596                Slog.w(TAG, msg);
15597                throw new SecurityException(msg);
15598            }
15599            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15600            if (stickies != null) {
15601                ArrayList<Intent> list = stickies.get(intent.getAction());
15602                if (list != null) {
15603                    int N = list.size();
15604                    int i;
15605                    for (i=0; i<N; i++) {
15606                        if (intent.filterEquals(list.get(i))) {
15607                            list.remove(i);
15608                            break;
15609                        }
15610                    }
15611                    if (list.size() <= 0) {
15612                        stickies.remove(intent.getAction());
15613                    }
15614                }
15615                if (stickies.size() <= 0) {
15616                    mStickyBroadcasts.remove(userId);
15617                }
15618            }
15619        }
15620    }
15621
15622    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15623            String resultData, Bundle resultExtras, boolean resultAbort) {
15624        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15625        if (r == null) {
15626            Slog.w(TAG, "finishReceiver called but not found on queue");
15627            return false;
15628        }
15629
15630        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15631    }
15632
15633    void backgroundServicesFinishedLocked(int userId) {
15634        for (BroadcastQueue queue : mBroadcastQueues) {
15635            queue.backgroundServicesFinishedLocked(userId);
15636        }
15637    }
15638
15639    public void finishReceiver(IBinder who, int resultCode, String resultData,
15640            Bundle resultExtras, boolean resultAbort) {
15641        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15642
15643        // Refuse possible leaked file descriptors
15644        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15645            throw new IllegalArgumentException("File descriptors passed in Bundle");
15646        }
15647
15648        final long origId = Binder.clearCallingIdentity();
15649        try {
15650            boolean doNext = false;
15651            BroadcastRecord r;
15652
15653            synchronized(this) {
15654                r = broadcastRecordForReceiverLocked(who);
15655                if (r != null) {
15656                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15657                        resultData, resultExtras, resultAbort, true);
15658                }
15659            }
15660
15661            if (doNext) {
15662                r.queue.processNextBroadcast(false);
15663            }
15664            trimApplications();
15665        } finally {
15666            Binder.restoreCallingIdentity(origId);
15667        }
15668    }
15669
15670    // =========================================================
15671    // INSTRUMENTATION
15672    // =========================================================
15673
15674    public boolean startInstrumentation(ComponentName className,
15675            String profileFile, int flags, Bundle arguments,
15676            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15677            int userId, String abiOverride) {
15678        enforceNotIsolatedCaller("startInstrumentation");
15679        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15680                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15681        // Refuse possible leaked file descriptors
15682        if (arguments != null && arguments.hasFileDescriptors()) {
15683            throw new IllegalArgumentException("File descriptors passed in Bundle");
15684        }
15685
15686        synchronized(this) {
15687            InstrumentationInfo ii = null;
15688            ApplicationInfo ai = null;
15689            try {
15690                ii = mContext.getPackageManager().getInstrumentationInfo(
15691                    className, STOCK_PM_FLAGS);
15692                ai = AppGlobals.getPackageManager().getApplicationInfo(
15693                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15694            } catch (PackageManager.NameNotFoundException e) {
15695            } catch (RemoteException e) {
15696            }
15697            if (ii == null) {
15698                reportStartInstrumentationFailure(watcher, className,
15699                        "Unable to find instrumentation info for: " + className);
15700                return false;
15701            }
15702            if (ai == null) {
15703                reportStartInstrumentationFailure(watcher, className,
15704                        "Unable to find instrumentation target package: " + ii.targetPackage);
15705                return false;
15706            }
15707
15708            int match = mContext.getPackageManager().checkSignatures(
15709                    ii.targetPackage, ii.packageName);
15710            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15711                String msg = "Permission Denial: starting instrumentation "
15712                        + className + " from pid="
15713                        + Binder.getCallingPid()
15714                        + ", uid=" + Binder.getCallingPid()
15715                        + " not allowed because package " + ii.packageName
15716                        + " does not have a signature matching the target "
15717                        + ii.targetPackage;
15718                reportStartInstrumentationFailure(watcher, className, msg);
15719                throw new SecurityException(msg);
15720            }
15721
15722            final long origId = Binder.clearCallingIdentity();
15723            // Instrumentation can kill and relaunch even persistent processes
15724            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15725                    "start instr");
15726            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15727            app.instrumentationClass = className;
15728            app.instrumentationInfo = ai;
15729            app.instrumentationProfileFile = profileFile;
15730            app.instrumentationArguments = arguments;
15731            app.instrumentationWatcher = watcher;
15732            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15733            app.instrumentationResultClass = className;
15734            Binder.restoreCallingIdentity(origId);
15735        }
15736
15737        return true;
15738    }
15739
15740    /**
15741     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15742     * error to the logs, but if somebody is watching, send the report there too.  This enables
15743     * the "am" command to report errors with more information.
15744     *
15745     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15746     * @param cn The component name of the instrumentation.
15747     * @param report The error report.
15748     */
15749    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15750            ComponentName cn, String report) {
15751        Slog.w(TAG, report);
15752        try {
15753            if (watcher != null) {
15754                Bundle results = new Bundle();
15755                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15756                results.putString("Error", report);
15757                watcher.instrumentationStatus(cn, -1, results);
15758            }
15759        } catch (RemoteException e) {
15760            Slog.w(TAG, e);
15761        }
15762    }
15763
15764    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15765        if (app.instrumentationWatcher != null) {
15766            try {
15767                // NOTE:  IInstrumentationWatcher *must* be oneway here
15768                app.instrumentationWatcher.instrumentationFinished(
15769                    app.instrumentationClass,
15770                    resultCode,
15771                    results);
15772            } catch (RemoteException e) {
15773            }
15774        }
15775        if (app.instrumentationUiAutomationConnection != null) {
15776            try {
15777                app.instrumentationUiAutomationConnection.shutdown();
15778            } catch (RemoteException re) {
15779                /* ignore */
15780            }
15781            // Only a UiAutomation can set this flag and now that
15782            // it is finished we make sure it is reset to its default.
15783            mUserIsMonkey = false;
15784        }
15785        app.instrumentationWatcher = null;
15786        app.instrumentationUiAutomationConnection = null;
15787        app.instrumentationClass = null;
15788        app.instrumentationInfo = null;
15789        app.instrumentationProfileFile = null;
15790        app.instrumentationArguments = null;
15791
15792        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15793                "finished inst");
15794    }
15795
15796    public void finishInstrumentation(IApplicationThread target,
15797            int resultCode, Bundle results) {
15798        int userId = UserHandle.getCallingUserId();
15799        // Refuse possible leaked file descriptors
15800        if (results != null && results.hasFileDescriptors()) {
15801            throw new IllegalArgumentException("File descriptors passed in Intent");
15802        }
15803
15804        synchronized(this) {
15805            ProcessRecord app = getRecordForAppLocked(target);
15806            if (app == null) {
15807                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15808                return;
15809            }
15810            final long origId = Binder.clearCallingIdentity();
15811            finishInstrumentationLocked(app, resultCode, results);
15812            Binder.restoreCallingIdentity(origId);
15813        }
15814    }
15815
15816    // =========================================================
15817    // CONFIGURATION
15818    // =========================================================
15819
15820    public ConfigurationInfo getDeviceConfigurationInfo() {
15821        ConfigurationInfo config = new ConfigurationInfo();
15822        synchronized (this) {
15823            config.reqTouchScreen = mConfiguration.touchscreen;
15824            config.reqKeyboardType = mConfiguration.keyboard;
15825            config.reqNavigation = mConfiguration.navigation;
15826            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15827                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15828                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15829            }
15830            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15831                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15832                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15833            }
15834            config.reqGlEsVersion = GL_ES_VERSION;
15835        }
15836        return config;
15837    }
15838
15839    ActivityStack getFocusedStack() {
15840        return mStackSupervisor.getFocusedStack();
15841    }
15842
15843    public Configuration getConfiguration() {
15844        Configuration ci;
15845        synchronized(this) {
15846            ci = new Configuration(mConfiguration);
15847        }
15848        return ci;
15849    }
15850
15851    public void updatePersistentConfiguration(Configuration values) {
15852        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15853                "updateConfiguration()");
15854        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15855                "updateConfiguration()");
15856        if (values == null) {
15857            throw new NullPointerException("Configuration must not be null");
15858        }
15859
15860        synchronized(this) {
15861            final long origId = Binder.clearCallingIdentity();
15862            updateConfigurationLocked(values, null, true, false);
15863            Binder.restoreCallingIdentity(origId);
15864        }
15865    }
15866
15867    public void updateConfiguration(Configuration values) {
15868        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15869                "updateConfiguration()");
15870
15871        synchronized(this) {
15872            if (values == null && mWindowManager != null) {
15873                // sentinel: fetch the current configuration from the window manager
15874                values = mWindowManager.computeNewConfiguration();
15875            }
15876
15877            if (mWindowManager != null) {
15878                mProcessList.applyDisplaySize(mWindowManager);
15879            }
15880
15881            final long origId = Binder.clearCallingIdentity();
15882            if (values != null) {
15883                Settings.System.clearConfiguration(values);
15884            }
15885            updateConfigurationLocked(values, null, false, false);
15886            Binder.restoreCallingIdentity(origId);
15887        }
15888    }
15889
15890    /**
15891     * Do either or both things: (1) change the current configuration, and (2)
15892     * make sure the given activity is running with the (now) current
15893     * configuration.  Returns true if the activity has been left running, or
15894     * false if <var>starting</var> is being destroyed to match the new
15895     * configuration.
15896     * @param persistent TODO
15897     */
15898    boolean updateConfigurationLocked(Configuration values,
15899            ActivityRecord starting, boolean persistent, boolean initLocale) {
15900        int changes = 0;
15901
15902        if (values != null) {
15903            Configuration newConfig = new Configuration(mConfiguration);
15904            changes = newConfig.updateFrom(values);
15905            if (changes != 0) {
15906                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15907                    Slog.i(TAG, "Updating configuration to: " + values);
15908                }
15909
15910                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15911
15912                if (values.locale != null && !initLocale) {
15913                    saveLocaleLocked(values.locale,
15914                                     !values.locale.equals(mConfiguration.locale),
15915                                     values.userSetLocale);
15916                }
15917
15918                mConfigurationSeq++;
15919                if (mConfigurationSeq <= 0) {
15920                    mConfigurationSeq = 1;
15921                }
15922                newConfig.seq = mConfigurationSeq;
15923                mConfiguration = newConfig;
15924                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15925                //mUsageStatsService.noteStartConfig(newConfig);
15926
15927                final Configuration configCopy = new Configuration(mConfiguration);
15928
15929                // TODO: If our config changes, should we auto dismiss any currently
15930                // showing dialogs?
15931                mShowDialogs = shouldShowDialogs(newConfig);
15932
15933                AttributeCache ac = AttributeCache.instance();
15934                if (ac != null) {
15935                    ac.updateConfiguration(configCopy);
15936                }
15937
15938                // Make sure all resources in our process are updated
15939                // right now, so that anyone who is going to retrieve
15940                // resource values after we return will be sure to get
15941                // the new ones.  This is especially important during
15942                // boot, where the first config change needs to guarantee
15943                // all resources have that config before following boot
15944                // code is executed.
15945                mSystemThread.applyConfigurationToResources(configCopy);
15946
15947                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15948                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15949                    msg.obj = new Configuration(configCopy);
15950                    mHandler.sendMessage(msg);
15951                }
15952
15953                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15954                    ProcessRecord app = mLruProcesses.get(i);
15955                    try {
15956                        if (app.thread != null) {
15957                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15958                                    + app.processName + " new config " + mConfiguration);
15959                            app.thread.scheduleConfigurationChanged(configCopy);
15960                        }
15961                    } catch (Exception e) {
15962                    }
15963                }
15964                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15965                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15966                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15967                        | Intent.FLAG_RECEIVER_FOREGROUND);
15968                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15969                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15970                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15971                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15972                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15973                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15974                    broadcastIntentLocked(null, null, intent,
15975                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15976                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15977                }
15978            }
15979        }
15980
15981        boolean kept = true;
15982        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15983        // mainStack is null during startup.
15984        if (mainStack != null) {
15985            if (changes != 0 && starting == null) {
15986                // If the configuration changed, and the caller is not already
15987                // in the process of starting an activity, then find the top
15988                // activity to check if its configuration needs to change.
15989                starting = mainStack.topRunningActivityLocked(null);
15990            }
15991
15992            if (starting != null) {
15993                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15994                // And we need to make sure at this point that all other activities
15995                // are made visible with the correct configuration.
15996                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15997            }
15998        }
15999
16000        if (values != null && mWindowManager != null) {
16001            mWindowManager.setNewConfiguration(mConfiguration);
16002        }
16003
16004        return kept;
16005    }
16006
16007    /**
16008     * Decide based on the configuration whether we should shouw the ANR,
16009     * crash, etc dialogs.  The idea is that if there is no affordnace to
16010     * press the on-screen buttons, we shouldn't show the dialog.
16011     *
16012     * A thought: SystemUI might also want to get told about this, the Power
16013     * dialog / global actions also might want different behaviors.
16014     */
16015    private static final boolean shouldShowDialogs(Configuration config) {
16016        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16017                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16018    }
16019
16020    /**
16021     * Save the locale.  You must be inside a synchronized (this) block.
16022     */
16023    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16024        if(isDiff) {
16025            SystemProperties.set("user.language", l.getLanguage());
16026            SystemProperties.set("user.region", l.getCountry());
16027        }
16028
16029        if(isPersist) {
16030            SystemProperties.set("persist.sys.language", l.getLanguage());
16031            SystemProperties.set("persist.sys.country", l.getCountry());
16032            SystemProperties.set("persist.sys.localevar", l.getVariant());
16033        }
16034    }
16035
16036    @Override
16037    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16038        synchronized (this) {
16039            ActivityRecord srec = ActivityRecord.forToken(token);
16040            if (srec.task != null && srec.task.stack != null) {
16041                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16042            }
16043        }
16044        return false;
16045    }
16046
16047    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16048            Intent resultData) {
16049
16050        synchronized (this) {
16051            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16052            if (stack != null) {
16053                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16054            }
16055            return false;
16056        }
16057    }
16058
16059    public int getLaunchedFromUid(IBinder activityToken) {
16060        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16061        if (srec == null) {
16062            return -1;
16063        }
16064        return srec.launchedFromUid;
16065    }
16066
16067    public String getLaunchedFromPackage(IBinder activityToken) {
16068        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16069        if (srec == null) {
16070            return null;
16071        }
16072        return srec.launchedFromPackage;
16073    }
16074
16075    // =========================================================
16076    // LIFETIME MANAGEMENT
16077    // =========================================================
16078
16079    // Returns which broadcast queue the app is the current [or imminent] receiver
16080    // on, or 'null' if the app is not an active broadcast recipient.
16081    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16082        BroadcastRecord r = app.curReceiver;
16083        if (r != null) {
16084            return r.queue;
16085        }
16086
16087        // It's not the current receiver, but it might be starting up to become one
16088        synchronized (this) {
16089            for (BroadcastQueue queue : mBroadcastQueues) {
16090                r = queue.mPendingBroadcast;
16091                if (r != null && r.curApp == app) {
16092                    // found it; report which queue it's in
16093                    return queue;
16094                }
16095            }
16096        }
16097
16098        return null;
16099    }
16100
16101    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16102            boolean doingAll, long now) {
16103        if (mAdjSeq == app.adjSeq) {
16104            // This adjustment has already been computed.
16105            return app.curRawAdj;
16106        }
16107
16108        if (app.thread == null) {
16109            app.adjSeq = mAdjSeq;
16110            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16111            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16112            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16113        }
16114
16115        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16116        app.adjSource = null;
16117        app.adjTarget = null;
16118        app.empty = false;
16119        app.cached = false;
16120
16121        final int activitiesSize = app.activities.size();
16122
16123        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16124            // The max adjustment doesn't allow this app to be anything
16125            // below foreground, so it is not worth doing work for it.
16126            app.adjType = "fixed";
16127            app.adjSeq = mAdjSeq;
16128            app.curRawAdj = app.maxAdj;
16129            app.foregroundActivities = false;
16130            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16131            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16132            // System processes can do UI, and when they do we want to have
16133            // them trim their memory after the user leaves the UI.  To
16134            // facilitate this, here we need to determine whether or not it
16135            // is currently showing UI.
16136            app.systemNoUi = true;
16137            if (app == TOP_APP) {
16138                app.systemNoUi = false;
16139            } else if (activitiesSize > 0) {
16140                for (int j = 0; j < activitiesSize; j++) {
16141                    final ActivityRecord r = app.activities.get(j);
16142                    if (r.visible) {
16143                        app.systemNoUi = false;
16144                    }
16145                }
16146            }
16147            if (!app.systemNoUi) {
16148                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16149            }
16150            return (app.curAdj=app.maxAdj);
16151        }
16152
16153        app.systemNoUi = false;
16154
16155        // Determine the importance of the process, starting with most
16156        // important to least, and assign an appropriate OOM adjustment.
16157        int adj;
16158        int schedGroup;
16159        int procState;
16160        boolean foregroundActivities = false;
16161        BroadcastQueue queue;
16162        if (app == TOP_APP) {
16163            // The last app on the list is the foreground app.
16164            adj = ProcessList.FOREGROUND_APP_ADJ;
16165            schedGroup = Process.THREAD_GROUP_DEFAULT;
16166            app.adjType = "top-activity";
16167            foregroundActivities = true;
16168            procState = ActivityManager.PROCESS_STATE_TOP;
16169        } else if (app.instrumentationClass != null) {
16170            // Don't want to kill running instrumentation.
16171            adj = ProcessList.FOREGROUND_APP_ADJ;
16172            schedGroup = Process.THREAD_GROUP_DEFAULT;
16173            app.adjType = "instrumentation";
16174            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16175        } else if ((queue = isReceivingBroadcast(app)) != null) {
16176            // An app that is currently receiving a broadcast also
16177            // counts as being in the foreground for OOM killer purposes.
16178            // It's placed in a sched group based on the nature of the
16179            // broadcast as reflected by which queue it's active in.
16180            adj = ProcessList.FOREGROUND_APP_ADJ;
16181            schedGroup = (queue == mFgBroadcastQueue)
16182                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16183            app.adjType = "broadcast";
16184            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16185        } else if (app.executingServices.size() > 0) {
16186            // An app that is currently executing a service callback also
16187            // counts as being in the foreground.
16188            adj = ProcessList.FOREGROUND_APP_ADJ;
16189            schedGroup = app.execServicesFg ?
16190                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16191            app.adjType = "exec-service";
16192            procState = ActivityManager.PROCESS_STATE_SERVICE;
16193            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16194        } else {
16195            // As far as we know the process is empty.  We may change our mind later.
16196            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16197            // At this point we don't actually know the adjustment.  Use the cached adj
16198            // value that the caller wants us to.
16199            adj = cachedAdj;
16200            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16201            app.cached = true;
16202            app.empty = true;
16203            app.adjType = "cch-empty";
16204        }
16205
16206        // Examine all activities if not already foreground.
16207        if (!foregroundActivities && activitiesSize > 0) {
16208            for (int j = 0; j < activitiesSize; j++) {
16209                final ActivityRecord r = app.activities.get(j);
16210                if (r.app != app) {
16211                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16212                            + app + "?!?");
16213                    continue;
16214                }
16215                if (r.visible) {
16216                    // App has a visible activity; only upgrade adjustment.
16217                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16218                        adj = ProcessList.VISIBLE_APP_ADJ;
16219                        app.adjType = "visible";
16220                    }
16221                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16222                        procState = ActivityManager.PROCESS_STATE_TOP;
16223                    }
16224                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16225                    app.cached = false;
16226                    app.empty = false;
16227                    foregroundActivities = true;
16228                    break;
16229                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16230                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16231                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16232                        app.adjType = "pausing";
16233                    }
16234                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16235                        procState = ActivityManager.PROCESS_STATE_TOP;
16236                    }
16237                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16238                    app.cached = false;
16239                    app.empty = false;
16240                    foregroundActivities = true;
16241                } else if (r.state == ActivityState.STOPPING) {
16242                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16243                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16244                        app.adjType = "stopping";
16245                    }
16246                    // For the process state, we will at this point consider the
16247                    // process to be cached.  It will be cached either as an activity
16248                    // or empty depending on whether the activity is finishing.  We do
16249                    // this so that we can treat the process as cached for purposes of
16250                    // memory trimming (determing current memory level, trim command to
16251                    // send to process) since there can be an arbitrary number of stopping
16252                    // processes and they should soon all go into the cached state.
16253                    if (!r.finishing) {
16254                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16255                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16256                        }
16257                    }
16258                    app.cached = false;
16259                    app.empty = false;
16260                    foregroundActivities = true;
16261                } else {
16262                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16263                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16264                        app.adjType = "cch-act";
16265                    }
16266                }
16267            }
16268        }
16269
16270        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16271            if (app.foregroundServices) {
16272                // The user is aware of this app, so make it visible.
16273                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16274                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16275                app.cached = false;
16276                app.adjType = "fg-service";
16277                schedGroup = Process.THREAD_GROUP_DEFAULT;
16278            } else if (app.forcingToForeground != null) {
16279                // The user is aware of this app, so make it visible.
16280                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16281                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16282                app.cached = false;
16283                app.adjType = "force-fg";
16284                app.adjSource = app.forcingToForeground;
16285                schedGroup = Process.THREAD_GROUP_DEFAULT;
16286            }
16287        }
16288
16289        if (app == mHeavyWeightProcess) {
16290            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16291                // We don't want to kill the current heavy-weight process.
16292                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16293                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16294                app.cached = false;
16295                app.adjType = "heavy";
16296            }
16297            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16298                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16299            }
16300        }
16301
16302        if (app == mHomeProcess) {
16303            if (adj > ProcessList.HOME_APP_ADJ) {
16304                // This process is hosting what we currently consider to be the
16305                // home app, so we don't want to let it go into the background.
16306                adj = ProcessList.HOME_APP_ADJ;
16307                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16308                app.cached = false;
16309                app.adjType = "home";
16310            }
16311            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16312                procState = ActivityManager.PROCESS_STATE_HOME;
16313            }
16314        }
16315
16316        if (app == mPreviousProcess && app.activities.size() > 0) {
16317            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16318                // This was the previous process that showed UI to the user.
16319                // We want to try to keep it around more aggressively, to give
16320                // a good experience around switching between two apps.
16321                adj = ProcessList.PREVIOUS_APP_ADJ;
16322                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16323                app.cached = false;
16324                app.adjType = "previous";
16325            }
16326            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16327                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16328            }
16329        }
16330
16331        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16332                + " reason=" + app.adjType);
16333
16334        // By default, we use the computed adjustment.  It may be changed if
16335        // there are applications dependent on our services or providers, but
16336        // this gives us a baseline and makes sure we don't get into an
16337        // infinite recursion.
16338        app.adjSeq = mAdjSeq;
16339        app.curRawAdj = adj;
16340        app.hasStartedServices = false;
16341
16342        if (mBackupTarget != null && app == mBackupTarget.app) {
16343            // If possible we want to avoid killing apps while they're being backed up
16344            if (adj > ProcessList.BACKUP_APP_ADJ) {
16345                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16346                adj = ProcessList.BACKUP_APP_ADJ;
16347                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16348                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16349                }
16350                app.adjType = "backup";
16351                app.cached = false;
16352            }
16353            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16354                procState = ActivityManager.PROCESS_STATE_BACKUP;
16355            }
16356        }
16357
16358        boolean mayBeTop = false;
16359
16360        for (int is = app.services.size()-1;
16361                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16362                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16363                        || procState > ActivityManager.PROCESS_STATE_TOP);
16364                is--) {
16365            ServiceRecord s = app.services.valueAt(is);
16366            if (s.startRequested) {
16367                app.hasStartedServices = true;
16368                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16369                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16370                }
16371                if (app.hasShownUi && app != mHomeProcess) {
16372                    // If this process has shown some UI, let it immediately
16373                    // go to the LRU list because it may be pretty heavy with
16374                    // UI stuff.  We'll tag it with a label just to help
16375                    // debug and understand what is going on.
16376                    if (adj > ProcessList.SERVICE_ADJ) {
16377                        app.adjType = "cch-started-ui-services";
16378                    }
16379                } else {
16380                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16381                        // This service has seen some activity within
16382                        // recent memory, so we will keep its process ahead
16383                        // of the background processes.
16384                        if (adj > ProcessList.SERVICE_ADJ) {
16385                            adj = ProcessList.SERVICE_ADJ;
16386                            app.adjType = "started-services";
16387                            app.cached = false;
16388                        }
16389                    }
16390                    // If we have let the service slide into the background
16391                    // state, still have some text describing what it is doing
16392                    // even though the service no longer has an impact.
16393                    if (adj > ProcessList.SERVICE_ADJ) {
16394                        app.adjType = "cch-started-services";
16395                    }
16396                }
16397            }
16398            for (int conni = s.connections.size()-1;
16399                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16400                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16401                            || procState > ActivityManager.PROCESS_STATE_TOP);
16402                    conni--) {
16403                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16404                for (int i = 0;
16405                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16406                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16407                                || procState > ActivityManager.PROCESS_STATE_TOP);
16408                        i++) {
16409                    // XXX should compute this based on the max of
16410                    // all connected clients.
16411                    ConnectionRecord cr = clist.get(i);
16412                    if (cr.binding.client == app) {
16413                        // Binding to ourself is not interesting.
16414                        continue;
16415                    }
16416                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16417                        ProcessRecord client = cr.binding.client;
16418                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16419                                TOP_APP, doingAll, now);
16420                        int clientProcState = client.curProcState;
16421                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16422                            // If the other app is cached for any reason, for purposes here
16423                            // we are going to consider it empty.  The specific cached state
16424                            // doesn't propagate except under certain conditions.
16425                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16426                        }
16427                        String adjType = null;
16428                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16429                            // Not doing bind OOM management, so treat
16430                            // this guy more like a started service.
16431                            if (app.hasShownUi && app != mHomeProcess) {
16432                                // If this process has shown some UI, let it immediately
16433                                // go to the LRU list because it may be pretty heavy with
16434                                // UI stuff.  We'll tag it with a label just to help
16435                                // debug and understand what is going on.
16436                                if (adj > clientAdj) {
16437                                    adjType = "cch-bound-ui-services";
16438                                }
16439                                app.cached = false;
16440                                clientAdj = adj;
16441                                clientProcState = procState;
16442                            } else {
16443                                if (now >= (s.lastActivity
16444                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16445                                    // This service has not seen activity within
16446                                    // recent memory, so allow it to drop to the
16447                                    // LRU list if there is no other reason to keep
16448                                    // it around.  We'll also tag it with a label just
16449                                    // to help debug and undertand what is going on.
16450                                    if (adj > clientAdj) {
16451                                        adjType = "cch-bound-services";
16452                                    }
16453                                    clientAdj = adj;
16454                                }
16455                            }
16456                        }
16457                        if (adj > clientAdj) {
16458                            // If this process has recently shown UI, and
16459                            // the process that is binding to it is less
16460                            // important than being visible, then we don't
16461                            // care about the binding as much as we care
16462                            // about letting this process get into the LRU
16463                            // list to be killed and restarted if needed for
16464                            // memory.
16465                            if (app.hasShownUi && app != mHomeProcess
16466                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16467                                adjType = "cch-bound-ui-services";
16468                            } else {
16469                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16470                                        |Context.BIND_IMPORTANT)) != 0) {
16471                                    adj = clientAdj;
16472                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16473                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16474                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16475                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16476                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16477                                    adj = clientAdj;
16478                                } else {
16479                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16480                                        adj = ProcessList.VISIBLE_APP_ADJ;
16481                                    }
16482                                }
16483                                if (!client.cached) {
16484                                    app.cached = false;
16485                                }
16486                                adjType = "service";
16487                            }
16488                        }
16489                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16490                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16491                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16492                            }
16493                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16494                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16495                                    // Special handling of clients who are in the top state.
16496                                    // We *may* want to consider this process to be in the
16497                                    // top state as well, but only if there is not another
16498                                    // reason for it to be running.  Being on the top is a
16499                                    // special state, meaning you are specifically running
16500                                    // for the current top app.  If the process is already
16501                                    // running in the background for some other reason, it
16502                                    // is more important to continue considering it to be
16503                                    // in the background state.
16504                                    mayBeTop = true;
16505                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16506                                } else {
16507                                    // Special handling for above-top states (persistent
16508                                    // processes).  These should not bring the current process
16509                                    // into the top state, since they are not on top.  Instead
16510                                    // give them the best state after that.
16511                                    clientProcState =
16512                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16513                                }
16514                            }
16515                        } else {
16516                            if (clientProcState <
16517                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16518                                clientProcState =
16519                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16520                            }
16521                        }
16522                        if (procState > clientProcState) {
16523                            procState = clientProcState;
16524                        }
16525                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16526                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16527                            app.pendingUiClean = true;
16528                        }
16529                        if (adjType != null) {
16530                            app.adjType = adjType;
16531                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16532                                    .REASON_SERVICE_IN_USE;
16533                            app.adjSource = cr.binding.client;
16534                            app.adjSourceProcState = clientProcState;
16535                            app.adjTarget = s.name;
16536                        }
16537                    }
16538                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16539                        app.treatLikeActivity = true;
16540                    }
16541                    final ActivityRecord a = cr.activity;
16542                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16543                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16544                                (a.visible || a.state == ActivityState.RESUMED
16545                                 || a.state == ActivityState.PAUSING)) {
16546                            adj = ProcessList.FOREGROUND_APP_ADJ;
16547                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16548                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16549                            }
16550                            app.cached = false;
16551                            app.adjType = "service";
16552                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16553                                    .REASON_SERVICE_IN_USE;
16554                            app.adjSource = a;
16555                            app.adjSourceProcState = procState;
16556                            app.adjTarget = s.name;
16557                        }
16558                    }
16559                }
16560            }
16561        }
16562
16563        for (int provi = app.pubProviders.size()-1;
16564                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16565                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16566                        || procState > ActivityManager.PROCESS_STATE_TOP);
16567                provi--) {
16568            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16569            for (int i = cpr.connections.size()-1;
16570                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16571                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16572                            || procState > ActivityManager.PROCESS_STATE_TOP);
16573                    i--) {
16574                ContentProviderConnection conn = cpr.connections.get(i);
16575                ProcessRecord client = conn.client;
16576                if (client == app) {
16577                    // Being our own client is not interesting.
16578                    continue;
16579                }
16580                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16581                int clientProcState = client.curProcState;
16582                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16583                    // If the other app is cached for any reason, for purposes here
16584                    // we are going to consider it empty.
16585                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16586                }
16587                if (adj > clientAdj) {
16588                    if (app.hasShownUi && app != mHomeProcess
16589                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16590                        app.adjType = "cch-ui-provider";
16591                    } else {
16592                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16593                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16594                        app.adjType = "provider";
16595                    }
16596                    app.cached &= client.cached;
16597                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16598                            .REASON_PROVIDER_IN_USE;
16599                    app.adjSource = client;
16600                    app.adjSourceProcState = clientProcState;
16601                    app.adjTarget = cpr.name;
16602                }
16603                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16604                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16605                        // Special handling of clients who are in the top state.
16606                        // We *may* want to consider this process to be in the
16607                        // top state as well, but only if there is not another
16608                        // reason for it to be running.  Being on the top is a
16609                        // special state, meaning you are specifically running
16610                        // for the current top app.  If the process is already
16611                        // running in the background for some other reason, it
16612                        // is more important to continue considering it to be
16613                        // in the background state.
16614                        mayBeTop = true;
16615                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16616                    } else {
16617                        // Special handling for above-top states (persistent
16618                        // processes).  These should not bring the current process
16619                        // into the top state, since they are not on top.  Instead
16620                        // give them the best state after that.
16621                        clientProcState =
16622                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16623                    }
16624                }
16625                if (procState > clientProcState) {
16626                    procState = clientProcState;
16627                }
16628                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16629                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16630                }
16631            }
16632            // If the provider has external (non-framework) process
16633            // dependencies, ensure that its adjustment is at least
16634            // FOREGROUND_APP_ADJ.
16635            if (cpr.hasExternalProcessHandles()) {
16636                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16637                    adj = ProcessList.FOREGROUND_APP_ADJ;
16638                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16639                    app.cached = false;
16640                    app.adjType = "provider";
16641                    app.adjTarget = cpr.name;
16642                }
16643                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16644                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16645                }
16646            }
16647        }
16648
16649        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16650            // A client of one of our services or providers is in the top state.  We
16651            // *may* want to be in the top state, but not if we are already running in
16652            // the background for some other reason.  For the decision here, we are going
16653            // to pick out a few specific states that we want to remain in when a client
16654            // is top (states that tend to be longer-term) and otherwise allow it to go
16655            // to the top state.
16656            switch (procState) {
16657                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16658                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16659                case ActivityManager.PROCESS_STATE_SERVICE:
16660                    // These all are longer-term states, so pull them up to the top
16661                    // of the background states, but not all the way to the top state.
16662                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16663                    break;
16664                default:
16665                    // Otherwise, top is a better choice, so take it.
16666                    procState = ActivityManager.PROCESS_STATE_TOP;
16667                    break;
16668            }
16669        }
16670
16671        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16672            if (app.hasClientActivities) {
16673                // This is a cached process, but with client activities.  Mark it so.
16674                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16675                app.adjType = "cch-client-act";
16676            } else if (app.treatLikeActivity) {
16677                // This is a cached process, but somebody wants us to treat it like it has
16678                // an activity, okay!
16679                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16680                app.adjType = "cch-as-act";
16681            }
16682        }
16683
16684        if (adj == ProcessList.SERVICE_ADJ) {
16685            if (doingAll) {
16686                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16687                mNewNumServiceProcs++;
16688                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16689                if (!app.serviceb) {
16690                    // This service isn't far enough down on the LRU list to
16691                    // normally be a B service, but if we are low on RAM and it
16692                    // is large we want to force it down since we would prefer to
16693                    // keep launcher over it.
16694                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16695                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16696                        app.serviceHighRam = true;
16697                        app.serviceb = true;
16698                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16699                    } else {
16700                        mNewNumAServiceProcs++;
16701                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16702                    }
16703                } else {
16704                    app.serviceHighRam = false;
16705                }
16706            }
16707            if (app.serviceb) {
16708                adj = ProcessList.SERVICE_B_ADJ;
16709            }
16710        }
16711
16712        app.curRawAdj = adj;
16713
16714        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16715        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16716        if (adj > app.maxAdj) {
16717            adj = app.maxAdj;
16718            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16719                schedGroup = Process.THREAD_GROUP_DEFAULT;
16720            }
16721        }
16722
16723        // Do final modification to adj.  Everything we do between here and applying
16724        // the final setAdj must be done in this function, because we will also use
16725        // it when computing the final cached adj later.  Note that we don't need to
16726        // worry about this for max adj above, since max adj will always be used to
16727        // keep it out of the cached vaues.
16728        app.curAdj = app.modifyRawOomAdj(adj);
16729        app.curSchedGroup = schedGroup;
16730        app.curProcState = procState;
16731        app.foregroundActivities = foregroundActivities;
16732
16733        return app.curRawAdj;
16734    }
16735
16736    /**
16737     * Schedule PSS collection of a process.
16738     */
16739    void requestPssLocked(ProcessRecord proc, int procState) {
16740        if (mPendingPssProcesses.contains(proc)) {
16741            return;
16742        }
16743        if (mPendingPssProcesses.size() == 0) {
16744            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16745        }
16746        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16747        proc.pssProcState = procState;
16748        mPendingPssProcesses.add(proc);
16749    }
16750
16751    /**
16752     * Schedule PSS collection of all processes.
16753     */
16754    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16755        if (!always) {
16756            if (now < (mLastFullPssTime +
16757                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16758                return;
16759            }
16760        }
16761        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16762        mLastFullPssTime = now;
16763        mFullPssPending = true;
16764        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16765        mPendingPssProcesses.clear();
16766        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16767            ProcessRecord app = mLruProcesses.get(i);
16768            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16769                app.pssProcState = app.setProcState;
16770                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16771                        isSleeping(), now);
16772                mPendingPssProcesses.add(app);
16773            }
16774        }
16775        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16776    }
16777
16778    /**
16779     * Ask a given process to GC right now.
16780     */
16781    final void performAppGcLocked(ProcessRecord app) {
16782        try {
16783            app.lastRequestedGc = SystemClock.uptimeMillis();
16784            if (app.thread != null) {
16785                if (app.reportLowMemory) {
16786                    app.reportLowMemory = false;
16787                    app.thread.scheduleLowMemory();
16788                } else {
16789                    app.thread.processInBackground();
16790                }
16791            }
16792        } catch (Exception e) {
16793            // whatever.
16794        }
16795    }
16796
16797    /**
16798     * Returns true if things are idle enough to perform GCs.
16799     */
16800    private final boolean canGcNowLocked() {
16801        boolean processingBroadcasts = false;
16802        for (BroadcastQueue q : mBroadcastQueues) {
16803            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16804                processingBroadcasts = true;
16805            }
16806        }
16807        return !processingBroadcasts
16808                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16809    }
16810
16811    /**
16812     * Perform GCs on all processes that are waiting for it, but only
16813     * if things are idle.
16814     */
16815    final void performAppGcsLocked() {
16816        final int N = mProcessesToGc.size();
16817        if (N <= 0) {
16818            return;
16819        }
16820        if (canGcNowLocked()) {
16821            while (mProcessesToGc.size() > 0) {
16822                ProcessRecord proc = mProcessesToGc.remove(0);
16823                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16824                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16825                            <= SystemClock.uptimeMillis()) {
16826                        // To avoid spamming the system, we will GC processes one
16827                        // at a time, waiting a few seconds between each.
16828                        performAppGcLocked(proc);
16829                        scheduleAppGcsLocked();
16830                        return;
16831                    } else {
16832                        // It hasn't been long enough since we last GCed this
16833                        // process...  put it in the list to wait for its time.
16834                        addProcessToGcListLocked(proc);
16835                        break;
16836                    }
16837                }
16838            }
16839
16840            scheduleAppGcsLocked();
16841        }
16842    }
16843
16844    /**
16845     * If all looks good, perform GCs on all processes waiting for them.
16846     */
16847    final void performAppGcsIfAppropriateLocked() {
16848        if (canGcNowLocked()) {
16849            performAppGcsLocked();
16850            return;
16851        }
16852        // Still not idle, wait some more.
16853        scheduleAppGcsLocked();
16854    }
16855
16856    /**
16857     * Schedule the execution of all pending app GCs.
16858     */
16859    final void scheduleAppGcsLocked() {
16860        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16861
16862        if (mProcessesToGc.size() > 0) {
16863            // Schedule a GC for the time to the next process.
16864            ProcessRecord proc = mProcessesToGc.get(0);
16865            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16866
16867            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16868            long now = SystemClock.uptimeMillis();
16869            if (when < (now+GC_TIMEOUT)) {
16870                when = now + GC_TIMEOUT;
16871            }
16872            mHandler.sendMessageAtTime(msg, when);
16873        }
16874    }
16875
16876    /**
16877     * Add a process to the array of processes waiting to be GCed.  Keeps the
16878     * list in sorted order by the last GC time.  The process can't already be
16879     * on the list.
16880     */
16881    final void addProcessToGcListLocked(ProcessRecord proc) {
16882        boolean added = false;
16883        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16884            if (mProcessesToGc.get(i).lastRequestedGc <
16885                    proc.lastRequestedGc) {
16886                added = true;
16887                mProcessesToGc.add(i+1, proc);
16888                break;
16889            }
16890        }
16891        if (!added) {
16892            mProcessesToGc.add(0, proc);
16893        }
16894    }
16895
16896    /**
16897     * Set up to ask a process to GC itself.  This will either do it
16898     * immediately, or put it on the list of processes to gc the next
16899     * time things are idle.
16900     */
16901    final void scheduleAppGcLocked(ProcessRecord app) {
16902        long now = SystemClock.uptimeMillis();
16903        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16904            return;
16905        }
16906        if (!mProcessesToGc.contains(app)) {
16907            addProcessToGcListLocked(app);
16908            scheduleAppGcsLocked();
16909        }
16910    }
16911
16912    final void checkExcessivePowerUsageLocked(boolean doKills) {
16913        updateCpuStatsNow();
16914
16915        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16916        boolean doWakeKills = doKills;
16917        boolean doCpuKills = doKills;
16918        if (mLastPowerCheckRealtime == 0) {
16919            doWakeKills = false;
16920        }
16921        if (mLastPowerCheckUptime == 0) {
16922            doCpuKills = false;
16923        }
16924        if (stats.isScreenOn()) {
16925            doWakeKills = false;
16926        }
16927        final long curRealtime = SystemClock.elapsedRealtime();
16928        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16929        final long curUptime = SystemClock.uptimeMillis();
16930        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16931        mLastPowerCheckRealtime = curRealtime;
16932        mLastPowerCheckUptime = curUptime;
16933        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16934            doWakeKills = false;
16935        }
16936        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16937            doCpuKills = false;
16938        }
16939        int i = mLruProcesses.size();
16940        while (i > 0) {
16941            i--;
16942            ProcessRecord app = mLruProcesses.get(i);
16943            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16944                long wtime;
16945                synchronized (stats) {
16946                    wtime = stats.getProcessWakeTime(app.info.uid,
16947                            app.pid, curRealtime);
16948                }
16949                long wtimeUsed = wtime - app.lastWakeTime;
16950                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16951                if (DEBUG_POWER) {
16952                    StringBuilder sb = new StringBuilder(128);
16953                    sb.append("Wake for ");
16954                    app.toShortString(sb);
16955                    sb.append(": over ");
16956                    TimeUtils.formatDuration(realtimeSince, sb);
16957                    sb.append(" used ");
16958                    TimeUtils.formatDuration(wtimeUsed, sb);
16959                    sb.append(" (");
16960                    sb.append((wtimeUsed*100)/realtimeSince);
16961                    sb.append("%)");
16962                    Slog.i(TAG, sb.toString());
16963                    sb.setLength(0);
16964                    sb.append("CPU for ");
16965                    app.toShortString(sb);
16966                    sb.append(": over ");
16967                    TimeUtils.formatDuration(uptimeSince, sb);
16968                    sb.append(" used ");
16969                    TimeUtils.formatDuration(cputimeUsed, sb);
16970                    sb.append(" (");
16971                    sb.append((cputimeUsed*100)/uptimeSince);
16972                    sb.append("%)");
16973                    Slog.i(TAG, sb.toString());
16974                }
16975                // If a process has held a wake lock for more
16976                // than 50% of the time during this period,
16977                // that sounds bad.  Kill!
16978                if (doWakeKills && realtimeSince > 0
16979                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16980                    synchronized (stats) {
16981                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16982                                realtimeSince, wtimeUsed);
16983                    }
16984                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16985                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16986                } else if (doCpuKills && uptimeSince > 0
16987                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16988                    synchronized (stats) {
16989                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16990                                uptimeSince, cputimeUsed);
16991                    }
16992                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16993                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16994                } else {
16995                    app.lastWakeTime = wtime;
16996                    app.lastCpuTime = app.curCpuTime;
16997                }
16998            }
16999        }
17000    }
17001
17002    private final boolean applyOomAdjLocked(ProcessRecord app,
17003            ProcessRecord TOP_APP, boolean doingAll, long now) {
17004        boolean success = true;
17005
17006        if (app.curRawAdj != app.setRawAdj) {
17007            app.setRawAdj = app.curRawAdj;
17008        }
17009
17010        int changes = 0;
17011
17012        if (app.curAdj != app.setAdj) {
17013            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17014            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17015                TAG, "Set " + app.pid + " " + app.processName +
17016                " adj " + app.curAdj + ": " + app.adjType);
17017            app.setAdj = app.curAdj;
17018        }
17019
17020        if (app.setSchedGroup != app.curSchedGroup) {
17021            app.setSchedGroup = app.curSchedGroup;
17022            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17023                    "Setting process group of " + app.processName
17024                    + " to " + app.curSchedGroup);
17025            if (app.waitingToKill != null &&
17026                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17027                app.kill(app.waitingToKill, true);
17028                success = false;
17029            } else {
17030                if (true) {
17031                    long oldId = Binder.clearCallingIdentity();
17032                    try {
17033                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17034                    } catch (Exception e) {
17035                        Slog.w(TAG, "Failed setting process group of " + app.pid
17036                                + " to " + app.curSchedGroup);
17037                        e.printStackTrace();
17038                    } finally {
17039                        Binder.restoreCallingIdentity(oldId);
17040                    }
17041                } else {
17042                    if (app.thread != null) {
17043                        try {
17044                            app.thread.setSchedulingGroup(app.curSchedGroup);
17045                        } catch (RemoteException e) {
17046                        }
17047                    }
17048                }
17049                Process.setSwappiness(app.pid,
17050                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17051            }
17052        }
17053        if (app.repForegroundActivities != app.foregroundActivities) {
17054            app.repForegroundActivities = app.foregroundActivities;
17055            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17056        }
17057        if (app.repProcState != app.curProcState) {
17058            app.repProcState = app.curProcState;
17059            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17060            if (app.thread != null) {
17061                try {
17062                    if (false) {
17063                        //RuntimeException h = new RuntimeException("here");
17064                        Slog.i(TAG, "Sending new process state " + app.repProcState
17065                                + " to " + app /*, h*/);
17066                    }
17067                    app.thread.setProcessState(app.repProcState);
17068                } catch (RemoteException e) {
17069                }
17070            }
17071        }
17072        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17073                app.setProcState)) {
17074            app.lastStateTime = now;
17075            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17076                    isSleeping(), now);
17077            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17078                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17079                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17080                    + (app.nextPssTime-now) + ": " + app);
17081        } else {
17082            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17083                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17084                requestPssLocked(app, app.setProcState);
17085                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17086                        isSleeping(), now);
17087            } else if (false && DEBUG_PSS) {
17088                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17089            }
17090        }
17091        if (app.setProcState != app.curProcState) {
17092            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17093                    "Proc state change of " + app.processName
17094                    + " to " + app.curProcState);
17095            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17096            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17097            if (setImportant && !curImportant) {
17098                // This app is no longer something we consider important enough to allow to
17099                // use arbitrary amounts of battery power.  Note
17100                // its current wake lock time to later know to kill it if
17101                // it is not behaving well.
17102                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17103                synchronized (stats) {
17104                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17105                            app.pid, SystemClock.elapsedRealtime());
17106                }
17107                app.lastCpuTime = app.curCpuTime;
17108
17109            }
17110            app.setProcState = app.curProcState;
17111            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17112                app.notCachedSinceIdle = false;
17113            }
17114            if (!doingAll) {
17115                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17116            } else {
17117                app.procStateChanged = true;
17118            }
17119        }
17120
17121        if (changes != 0) {
17122            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17123            int i = mPendingProcessChanges.size()-1;
17124            ProcessChangeItem item = null;
17125            while (i >= 0) {
17126                item = mPendingProcessChanges.get(i);
17127                if (item.pid == app.pid) {
17128                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17129                    break;
17130                }
17131                i--;
17132            }
17133            if (i < 0) {
17134                // No existing item in pending changes; need a new one.
17135                final int NA = mAvailProcessChanges.size();
17136                if (NA > 0) {
17137                    item = mAvailProcessChanges.remove(NA-1);
17138                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17139                } else {
17140                    item = new ProcessChangeItem();
17141                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17142                }
17143                item.changes = 0;
17144                item.pid = app.pid;
17145                item.uid = app.info.uid;
17146                if (mPendingProcessChanges.size() == 0) {
17147                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17148                            "*** Enqueueing dispatch processes changed!");
17149                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17150                }
17151                mPendingProcessChanges.add(item);
17152            }
17153            item.changes |= changes;
17154            item.processState = app.repProcState;
17155            item.foregroundActivities = app.repForegroundActivities;
17156            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17157                    + Integer.toHexString(System.identityHashCode(item))
17158                    + " " + app.toShortString() + ": changes=" + item.changes
17159                    + " procState=" + item.processState
17160                    + " foreground=" + item.foregroundActivities
17161                    + " type=" + app.adjType + " source=" + app.adjSource
17162                    + " target=" + app.adjTarget);
17163        }
17164
17165        return success;
17166    }
17167
17168    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17169        if (proc.thread != null) {
17170            if (proc.baseProcessTracker != null) {
17171                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17172            }
17173            if (proc.repProcState >= 0) {
17174                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17175                        proc.repProcState);
17176            }
17177        }
17178    }
17179
17180    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17181            ProcessRecord TOP_APP, boolean doingAll, long now) {
17182        if (app.thread == null) {
17183            return false;
17184        }
17185
17186        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17187
17188        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17189    }
17190
17191    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17192            boolean oomAdj) {
17193        if (isForeground != proc.foregroundServices) {
17194            proc.foregroundServices = isForeground;
17195            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17196                    proc.info.uid);
17197            if (isForeground) {
17198                if (curProcs == null) {
17199                    curProcs = new ArrayList<ProcessRecord>();
17200                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17201                }
17202                if (!curProcs.contains(proc)) {
17203                    curProcs.add(proc);
17204                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17205                            proc.info.packageName, proc.info.uid);
17206                }
17207            } else {
17208                if (curProcs != null) {
17209                    if (curProcs.remove(proc)) {
17210                        mBatteryStatsService.noteEvent(
17211                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17212                                proc.info.packageName, proc.info.uid);
17213                        if (curProcs.size() <= 0) {
17214                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17215                        }
17216                    }
17217                }
17218            }
17219            if (oomAdj) {
17220                updateOomAdjLocked();
17221            }
17222        }
17223    }
17224
17225    private final ActivityRecord resumedAppLocked() {
17226        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17227        String pkg;
17228        int uid;
17229        if (act != null) {
17230            pkg = act.packageName;
17231            uid = act.info.applicationInfo.uid;
17232        } else {
17233            pkg = null;
17234            uid = -1;
17235        }
17236        // Has the UID or resumed package name changed?
17237        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17238                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17239            if (mCurResumedPackage != null) {
17240                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17241                        mCurResumedPackage, mCurResumedUid);
17242            }
17243            mCurResumedPackage = pkg;
17244            mCurResumedUid = uid;
17245            if (mCurResumedPackage != null) {
17246                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17247                        mCurResumedPackage, mCurResumedUid);
17248            }
17249        }
17250        return act;
17251    }
17252
17253    final boolean updateOomAdjLocked(ProcessRecord app) {
17254        final ActivityRecord TOP_ACT = resumedAppLocked();
17255        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17256        final boolean wasCached = app.cached;
17257
17258        mAdjSeq++;
17259
17260        // This is the desired cached adjusment we want to tell it to use.
17261        // If our app is currently cached, we know it, and that is it.  Otherwise,
17262        // we don't know it yet, and it needs to now be cached we will then
17263        // need to do a complete oom adj.
17264        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17265                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17266        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17267                SystemClock.uptimeMillis());
17268        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17269            // Changed to/from cached state, so apps after it in the LRU
17270            // list may also be changed.
17271            updateOomAdjLocked();
17272        }
17273        return success;
17274    }
17275
17276    final void updateOomAdjLocked() {
17277        final ActivityRecord TOP_ACT = resumedAppLocked();
17278        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17279        final long now = SystemClock.uptimeMillis();
17280        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17281        final int N = mLruProcesses.size();
17282
17283        if (false) {
17284            RuntimeException e = new RuntimeException();
17285            e.fillInStackTrace();
17286            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17287        }
17288
17289        mAdjSeq++;
17290        mNewNumServiceProcs = 0;
17291        mNewNumAServiceProcs = 0;
17292
17293        final int emptyProcessLimit;
17294        final int cachedProcessLimit;
17295        if (mProcessLimit <= 0) {
17296            emptyProcessLimit = cachedProcessLimit = 0;
17297        } else if (mProcessLimit == 1) {
17298            emptyProcessLimit = 1;
17299            cachedProcessLimit = 0;
17300        } else {
17301            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17302            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17303        }
17304
17305        // Let's determine how many processes we have running vs.
17306        // how many slots we have for background processes; we may want
17307        // to put multiple processes in a slot of there are enough of
17308        // them.
17309        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17310                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17311        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17312        if (numEmptyProcs > cachedProcessLimit) {
17313            // If there are more empty processes than our limit on cached
17314            // processes, then use the cached process limit for the factor.
17315            // This ensures that the really old empty processes get pushed
17316            // down to the bottom, so if we are running low on memory we will
17317            // have a better chance at keeping around more cached processes
17318            // instead of a gazillion empty processes.
17319            numEmptyProcs = cachedProcessLimit;
17320        }
17321        int emptyFactor = numEmptyProcs/numSlots;
17322        if (emptyFactor < 1) emptyFactor = 1;
17323        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17324        if (cachedFactor < 1) cachedFactor = 1;
17325        int stepCached = 0;
17326        int stepEmpty = 0;
17327        int numCached = 0;
17328        int numEmpty = 0;
17329        int numTrimming = 0;
17330
17331        mNumNonCachedProcs = 0;
17332        mNumCachedHiddenProcs = 0;
17333
17334        // First update the OOM adjustment for each of the
17335        // application processes based on their current state.
17336        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17337        int nextCachedAdj = curCachedAdj+1;
17338        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17339        int nextEmptyAdj = curEmptyAdj+2;
17340        for (int i=N-1; i>=0; i--) {
17341            ProcessRecord app = mLruProcesses.get(i);
17342            if (!app.killedByAm && app.thread != null) {
17343                app.procStateChanged = false;
17344                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17345
17346                // If we haven't yet assigned the final cached adj
17347                // to the process, do that now.
17348                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17349                    switch (app.curProcState) {
17350                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17351                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17352                            // This process is a cached process holding activities...
17353                            // assign it the next cached value for that type, and then
17354                            // step that cached level.
17355                            app.curRawAdj = curCachedAdj;
17356                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17357                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17358                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17359                                    + ")");
17360                            if (curCachedAdj != nextCachedAdj) {
17361                                stepCached++;
17362                                if (stepCached >= cachedFactor) {
17363                                    stepCached = 0;
17364                                    curCachedAdj = nextCachedAdj;
17365                                    nextCachedAdj += 2;
17366                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17367                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17368                                    }
17369                                }
17370                            }
17371                            break;
17372                        default:
17373                            // For everything else, assign next empty cached process
17374                            // level and bump that up.  Note that this means that
17375                            // long-running services that have dropped down to the
17376                            // cached level will be treated as empty (since their process
17377                            // state is still as a service), which is what we want.
17378                            app.curRawAdj = curEmptyAdj;
17379                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17380                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17381                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17382                                    + ")");
17383                            if (curEmptyAdj != nextEmptyAdj) {
17384                                stepEmpty++;
17385                                if (stepEmpty >= emptyFactor) {
17386                                    stepEmpty = 0;
17387                                    curEmptyAdj = nextEmptyAdj;
17388                                    nextEmptyAdj += 2;
17389                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17390                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17391                                    }
17392                                }
17393                            }
17394                            break;
17395                    }
17396                }
17397
17398                applyOomAdjLocked(app, TOP_APP, true, now);
17399
17400                // Count the number of process types.
17401                switch (app.curProcState) {
17402                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17403                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17404                        mNumCachedHiddenProcs++;
17405                        numCached++;
17406                        if (numCached > cachedProcessLimit) {
17407                            app.kill("cached #" + numCached, true);
17408                        }
17409                        break;
17410                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17411                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17412                                && app.lastActivityTime < oldTime) {
17413                            app.kill("empty for "
17414                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17415                                    / 1000) + "s", true);
17416                        } else {
17417                            numEmpty++;
17418                            if (numEmpty > emptyProcessLimit) {
17419                                app.kill("empty #" + numEmpty, true);
17420                            }
17421                        }
17422                        break;
17423                    default:
17424                        mNumNonCachedProcs++;
17425                        break;
17426                }
17427
17428                if (app.isolated && app.services.size() <= 0) {
17429                    // If this is an isolated process, and there are no
17430                    // services running in it, then the process is no longer
17431                    // needed.  We agressively kill these because we can by
17432                    // definition not re-use the same process again, and it is
17433                    // good to avoid having whatever code was running in them
17434                    // left sitting around after no longer needed.
17435                    app.kill("isolated not needed", true);
17436                }
17437
17438                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17439                        && !app.killedByAm) {
17440                    numTrimming++;
17441                }
17442            }
17443        }
17444
17445        mNumServiceProcs = mNewNumServiceProcs;
17446
17447        // Now determine the memory trimming level of background processes.
17448        // Unfortunately we need to start at the back of the list to do this
17449        // properly.  We only do this if the number of background apps we
17450        // are managing to keep around is less than half the maximum we desire;
17451        // if we are keeping a good number around, we'll let them use whatever
17452        // memory they want.
17453        final int numCachedAndEmpty = numCached + numEmpty;
17454        int memFactor;
17455        if (numCached <= ProcessList.TRIM_CACHED_APPS
17456                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17457            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17458                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17459            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17460                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17461            } else {
17462                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17463            }
17464        } else {
17465            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17466        }
17467        // We always allow the memory level to go up (better).  We only allow it to go
17468        // down if we are in a state where that is allowed, *and* the total number of processes
17469        // has gone down since last time.
17470        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17471                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17472                + " last=" + mLastNumProcesses);
17473        if (memFactor > mLastMemoryLevel) {
17474            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17475                memFactor = mLastMemoryLevel;
17476                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17477            }
17478        }
17479        mLastMemoryLevel = memFactor;
17480        mLastNumProcesses = mLruProcesses.size();
17481        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17482        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17483        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17484            if (mLowRamStartTime == 0) {
17485                mLowRamStartTime = now;
17486            }
17487            int step = 0;
17488            int fgTrimLevel;
17489            switch (memFactor) {
17490                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17491                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17492                    break;
17493                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17494                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17495                    break;
17496                default:
17497                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17498                    break;
17499            }
17500            int factor = numTrimming/3;
17501            int minFactor = 2;
17502            if (mHomeProcess != null) minFactor++;
17503            if (mPreviousProcess != null) minFactor++;
17504            if (factor < minFactor) factor = minFactor;
17505            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17506            for (int i=N-1; i>=0; i--) {
17507                ProcessRecord app = mLruProcesses.get(i);
17508                if (allChanged || app.procStateChanged) {
17509                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17510                    app.procStateChanged = false;
17511                }
17512                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17513                        && !app.killedByAm) {
17514                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17515                        try {
17516                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17517                                    "Trimming memory of " + app.processName
17518                                    + " to " + curLevel);
17519                            app.thread.scheduleTrimMemory(curLevel);
17520                        } catch (RemoteException e) {
17521                        }
17522                        if (false) {
17523                            // For now we won't do this; our memory trimming seems
17524                            // to be good enough at this point that destroying
17525                            // activities causes more harm than good.
17526                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17527                                    && app != mHomeProcess && app != mPreviousProcess) {
17528                                // Need to do this on its own message because the stack may not
17529                                // be in a consistent state at this point.
17530                                // For these apps we will also finish their activities
17531                                // to help them free memory.
17532                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17533                            }
17534                        }
17535                    }
17536                    app.trimMemoryLevel = curLevel;
17537                    step++;
17538                    if (step >= factor) {
17539                        step = 0;
17540                        switch (curLevel) {
17541                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17542                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17543                                break;
17544                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17545                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17546                                break;
17547                        }
17548                    }
17549                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17550                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17551                            && app.thread != null) {
17552                        try {
17553                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17554                                    "Trimming memory of heavy-weight " + app.processName
17555                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17556                            app.thread.scheduleTrimMemory(
17557                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17558                        } catch (RemoteException e) {
17559                        }
17560                    }
17561                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17562                } else {
17563                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17564                            || app.systemNoUi) && app.pendingUiClean) {
17565                        // If this application is now in the background and it
17566                        // had done UI, then give it the special trim level to
17567                        // have it free UI resources.
17568                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17569                        if (app.trimMemoryLevel < level && app.thread != null) {
17570                            try {
17571                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17572                                        "Trimming memory of bg-ui " + app.processName
17573                                        + " to " + level);
17574                                app.thread.scheduleTrimMemory(level);
17575                            } catch (RemoteException e) {
17576                            }
17577                        }
17578                        app.pendingUiClean = false;
17579                    }
17580                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17581                        try {
17582                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17583                                    "Trimming memory of fg " + app.processName
17584                                    + " to " + fgTrimLevel);
17585                            app.thread.scheduleTrimMemory(fgTrimLevel);
17586                        } catch (RemoteException e) {
17587                        }
17588                    }
17589                    app.trimMemoryLevel = fgTrimLevel;
17590                }
17591            }
17592        } else {
17593            if (mLowRamStartTime != 0) {
17594                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17595                mLowRamStartTime = 0;
17596            }
17597            for (int i=N-1; i>=0; i--) {
17598                ProcessRecord app = mLruProcesses.get(i);
17599                if (allChanged || app.procStateChanged) {
17600                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17601                    app.procStateChanged = false;
17602                }
17603                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17604                        || app.systemNoUi) && app.pendingUiClean) {
17605                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17606                            && app.thread != null) {
17607                        try {
17608                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17609                                    "Trimming memory of ui hidden " + app.processName
17610                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17611                            app.thread.scheduleTrimMemory(
17612                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17613                        } catch (RemoteException e) {
17614                        }
17615                    }
17616                    app.pendingUiClean = false;
17617                }
17618                app.trimMemoryLevel = 0;
17619            }
17620        }
17621
17622        if (mAlwaysFinishActivities) {
17623            // Need to do this on its own message because the stack may not
17624            // be in a consistent state at this point.
17625            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17626        }
17627
17628        if (allChanged) {
17629            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17630        }
17631
17632        if (mProcessStats.shouldWriteNowLocked(now)) {
17633            mHandler.post(new Runnable() {
17634                @Override public void run() {
17635                    synchronized (ActivityManagerService.this) {
17636                        mProcessStats.writeStateAsyncLocked();
17637                    }
17638                }
17639            });
17640        }
17641
17642        if (DEBUG_OOM_ADJ) {
17643            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17644        }
17645    }
17646
17647    final void trimApplications() {
17648        synchronized (this) {
17649            int i;
17650
17651            // First remove any unused application processes whose package
17652            // has been removed.
17653            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17654                final ProcessRecord app = mRemovedProcesses.get(i);
17655                if (app.activities.size() == 0
17656                        && app.curReceiver == null && app.services.size() == 0) {
17657                    Slog.i(
17658                        TAG, "Exiting empty application process "
17659                        + app.processName + " ("
17660                        + (app.thread != null ? app.thread.asBinder() : null)
17661                        + ")\n");
17662                    if (app.pid > 0 && app.pid != MY_PID) {
17663                        app.kill("empty", false);
17664                    } else {
17665                        try {
17666                            app.thread.scheduleExit();
17667                        } catch (Exception e) {
17668                            // Ignore exceptions.
17669                        }
17670                    }
17671                    cleanUpApplicationRecordLocked(app, false, true, -1);
17672                    mRemovedProcesses.remove(i);
17673
17674                    if (app.persistent) {
17675                        addAppLocked(app.info, false, null /* ABI override */);
17676                    }
17677                }
17678            }
17679
17680            // Now update the oom adj for all processes.
17681            updateOomAdjLocked();
17682        }
17683    }
17684
17685    /** This method sends the specified signal to each of the persistent apps */
17686    public void signalPersistentProcesses(int sig) throws RemoteException {
17687        if (sig != Process.SIGNAL_USR1) {
17688            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17689        }
17690
17691        synchronized (this) {
17692            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17693                    != PackageManager.PERMISSION_GRANTED) {
17694                throw new SecurityException("Requires permission "
17695                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17696            }
17697
17698            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17699                ProcessRecord r = mLruProcesses.get(i);
17700                if (r.thread != null && r.persistent) {
17701                    Process.sendSignal(r.pid, sig);
17702                }
17703            }
17704        }
17705    }
17706
17707    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17708        if (proc == null || proc == mProfileProc) {
17709            proc = mProfileProc;
17710            profileType = mProfileType;
17711            clearProfilerLocked();
17712        }
17713        if (proc == null) {
17714            return;
17715        }
17716        try {
17717            proc.thread.profilerControl(false, null, profileType);
17718        } catch (RemoteException e) {
17719            throw new IllegalStateException("Process disappeared");
17720        }
17721    }
17722
17723    private void clearProfilerLocked() {
17724        if (mProfileFd != null) {
17725            try {
17726                mProfileFd.close();
17727            } catch (IOException e) {
17728            }
17729        }
17730        mProfileApp = null;
17731        mProfileProc = null;
17732        mProfileFile = null;
17733        mProfileType = 0;
17734        mAutoStopProfiler = false;
17735        mSamplingInterval = 0;
17736    }
17737
17738    public boolean profileControl(String process, int userId, boolean start,
17739            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17740
17741        try {
17742            synchronized (this) {
17743                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17744                // its own permission.
17745                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17746                        != PackageManager.PERMISSION_GRANTED) {
17747                    throw new SecurityException("Requires permission "
17748                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17749                }
17750
17751                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17752                    throw new IllegalArgumentException("null profile info or fd");
17753                }
17754
17755                ProcessRecord proc = null;
17756                if (process != null) {
17757                    proc = findProcessLocked(process, userId, "profileControl");
17758                }
17759
17760                if (start && (proc == null || proc.thread == null)) {
17761                    throw new IllegalArgumentException("Unknown process: " + process);
17762                }
17763
17764                if (start) {
17765                    stopProfilerLocked(null, 0);
17766                    setProfileApp(proc.info, proc.processName, profilerInfo);
17767                    mProfileProc = proc;
17768                    mProfileType = profileType;
17769                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17770                    try {
17771                        fd = fd.dup();
17772                    } catch (IOException e) {
17773                        fd = null;
17774                    }
17775                    profilerInfo.profileFd = fd;
17776                    proc.thread.profilerControl(start, profilerInfo, profileType);
17777                    fd = null;
17778                    mProfileFd = null;
17779                } else {
17780                    stopProfilerLocked(proc, profileType);
17781                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17782                        try {
17783                            profilerInfo.profileFd.close();
17784                        } catch (IOException e) {
17785                        }
17786                    }
17787                }
17788
17789                return true;
17790            }
17791        } catch (RemoteException e) {
17792            throw new IllegalStateException("Process disappeared");
17793        } finally {
17794            if (profilerInfo != null && profilerInfo.profileFd != null) {
17795                try {
17796                    profilerInfo.profileFd.close();
17797                } catch (IOException e) {
17798                }
17799            }
17800        }
17801    }
17802
17803    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17804        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17805                userId, true, ALLOW_FULL_ONLY, callName, null);
17806        ProcessRecord proc = null;
17807        try {
17808            int pid = Integer.parseInt(process);
17809            synchronized (mPidsSelfLocked) {
17810                proc = mPidsSelfLocked.get(pid);
17811            }
17812        } catch (NumberFormatException e) {
17813        }
17814
17815        if (proc == null) {
17816            ArrayMap<String, SparseArray<ProcessRecord>> all
17817                    = mProcessNames.getMap();
17818            SparseArray<ProcessRecord> procs = all.get(process);
17819            if (procs != null && procs.size() > 0) {
17820                proc = procs.valueAt(0);
17821                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17822                    for (int i=1; i<procs.size(); i++) {
17823                        ProcessRecord thisProc = procs.valueAt(i);
17824                        if (thisProc.userId == userId) {
17825                            proc = thisProc;
17826                            break;
17827                        }
17828                    }
17829                }
17830            }
17831        }
17832
17833        return proc;
17834    }
17835
17836    public boolean dumpHeap(String process, int userId, boolean managed,
17837            String path, ParcelFileDescriptor fd) throws RemoteException {
17838
17839        try {
17840            synchronized (this) {
17841                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17842                // its own permission (same as profileControl).
17843                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17844                        != PackageManager.PERMISSION_GRANTED) {
17845                    throw new SecurityException("Requires permission "
17846                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17847                }
17848
17849                if (fd == null) {
17850                    throw new IllegalArgumentException("null fd");
17851                }
17852
17853                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17854                if (proc == null || proc.thread == null) {
17855                    throw new IllegalArgumentException("Unknown process: " + process);
17856                }
17857
17858                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17859                if (!isDebuggable) {
17860                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17861                        throw new SecurityException("Process not debuggable: " + proc);
17862                    }
17863                }
17864
17865                proc.thread.dumpHeap(managed, path, fd);
17866                fd = null;
17867                return true;
17868            }
17869        } catch (RemoteException e) {
17870            throw new IllegalStateException("Process disappeared");
17871        } finally {
17872            if (fd != null) {
17873                try {
17874                    fd.close();
17875                } catch (IOException e) {
17876                }
17877            }
17878        }
17879    }
17880
17881    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17882    public void monitor() {
17883        synchronized (this) { }
17884    }
17885
17886    void onCoreSettingsChange(Bundle settings) {
17887        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17888            ProcessRecord processRecord = mLruProcesses.get(i);
17889            try {
17890                if (processRecord.thread != null) {
17891                    processRecord.thread.setCoreSettings(settings);
17892                }
17893            } catch (RemoteException re) {
17894                /* ignore */
17895            }
17896        }
17897    }
17898
17899    // Multi-user methods
17900
17901    /**
17902     * Start user, if its not already running, but don't bring it to foreground.
17903     */
17904    @Override
17905    public boolean startUserInBackground(final int userId) {
17906        return startUser(userId, /* foreground */ false);
17907    }
17908
17909    /**
17910     * Start user, if its not already running, and bring it to foreground.
17911     */
17912    boolean startUserInForeground(final int userId, Dialog dlg) {
17913        boolean result = startUser(userId, /* foreground */ true);
17914        dlg.dismiss();
17915        return result;
17916    }
17917
17918    /**
17919     * Refreshes the list of users related to the current user when either a
17920     * user switch happens or when a new related user is started in the
17921     * background.
17922     */
17923    private void updateCurrentProfileIdsLocked() {
17924        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17925                mCurrentUserId, false /* enabledOnly */);
17926        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17927        for (int i = 0; i < currentProfileIds.length; i++) {
17928            currentProfileIds[i] = profiles.get(i).id;
17929        }
17930        mCurrentProfileIds = currentProfileIds;
17931
17932        synchronized (mUserProfileGroupIdsSelfLocked) {
17933            mUserProfileGroupIdsSelfLocked.clear();
17934            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17935            for (int i = 0; i < users.size(); i++) {
17936                UserInfo user = users.get(i);
17937                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17938                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17939                }
17940            }
17941        }
17942    }
17943
17944    private Set getProfileIdsLocked(int userId) {
17945        Set userIds = new HashSet<Integer>();
17946        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17947                userId, false /* enabledOnly */);
17948        for (UserInfo user : profiles) {
17949            userIds.add(Integer.valueOf(user.id));
17950        }
17951        return userIds;
17952    }
17953
17954    @Override
17955    public boolean switchUser(final int userId) {
17956        String userName;
17957        synchronized (this) {
17958            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17959            if (userInfo == null) {
17960                Slog.w(TAG, "No user info for user #" + userId);
17961                return false;
17962            }
17963            if (userInfo.isManagedProfile()) {
17964                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17965                return false;
17966            }
17967            userName = userInfo.name;
17968            mTargetUserId = userId;
17969        }
17970        mHandler.removeMessages(START_USER_SWITCH_MSG);
17971        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17972        return true;
17973    }
17974
17975    private void showUserSwitchDialog(int userId, String userName) {
17976        // The dialog will show and then initiate the user switch by calling startUserInForeground
17977        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17978                true /* above system */);
17979        d.show();
17980    }
17981
17982    private boolean startUser(final int userId, final boolean foreground) {
17983        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17984                != PackageManager.PERMISSION_GRANTED) {
17985            String msg = "Permission Denial: switchUser() from pid="
17986                    + Binder.getCallingPid()
17987                    + ", uid=" + Binder.getCallingUid()
17988                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17989            Slog.w(TAG, msg);
17990            throw new SecurityException(msg);
17991        }
17992
17993        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17994
17995        final long ident = Binder.clearCallingIdentity();
17996        try {
17997            synchronized (this) {
17998                final int oldUserId = mCurrentUserId;
17999                if (oldUserId == userId) {
18000                    return true;
18001                }
18002
18003                mStackSupervisor.setLockTaskModeLocked(null, false);
18004
18005                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18006                if (userInfo == null) {
18007                    Slog.w(TAG, "No user info for user #" + userId);
18008                    return false;
18009                }
18010                if (foreground && userInfo.isManagedProfile()) {
18011                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18012                    return false;
18013                }
18014
18015                if (foreground) {
18016                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18017                            R.anim.screen_user_enter);
18018                }
18019
18020                boolean needStart = false;
18021
18022                // If the user we are switching to is not currently started, then
18023                // we need to start it now.
18024                if (mStartedUsers.get(userId) == null) {
18025                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18026                    updateStartedUserArrayLocked();
18027                    needStart = true;
18028                }
18029
18030                final Integer userIdInt = Integer.valueOf(userId);
18031                mUserLru.remove(userIdInt);
18032                mUserLru.add(userIdInt);
18033
18034                if (foreground) {
18035                    mCurrentUserId = userId;
18036                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18037                    updateCurrentProfileIdsLocked();
18038                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18039                    // Once the internal notion of the active user has switched, we lock the device
18040                    // with the option to show the user switcher on the keyguard.
18041                    mWindowManager.lockNow(null);
18042                } else {
18043                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18044                    updateCurrentProfileIdsLocked();
18045                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18046                    mUserLru.remove(currentUserIdInt);
18047                    mUserLru.add(currentUserIdInt);
18048                }
18049
18050                final UserStartedState uss = mStartedUsers.get(userId);
18051
18052                // Make sure user is in the started state.  If it is currently
18053                // stopping, we need to knock that off.
18054                if (uss.mState == UserStartedState.STATE_STOPPING) {
18055                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18056                    // so we can just fairly silently bring the user back from
18057                    // the almost-dead.
18058                    uss.mState = UserStartedState.STATE_RUNNING;
18059                    updateStartedUserArrayLocked();
18060                    needStart = true;
18061                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18062                    // This means ACTION_SHUTDOWN has been sent, so we will
18063                    // need to treat this as a new boot of the user.
18064                    uss.mState = UserStartedState.STATE_BOOTING;
18065                    updateStartedUserArrayLocked();
18066                    needStart = true;
18067                }
18068
18069                if (uss.mState == UserStartedState.STATE_BOOTING) {
18070                    // Booting up a new user, need to tell system services about it.
18071                    // Note that this is on the same handler as scheduling of broadcasts,
18072                    // which is important because it needs to go first.
18073                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18074                }
18075
18076                if (foreground) {
18077                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18078                            oldUserId));
18079                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18080                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18081                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18082                            oldUserId, userId, uss));
18083                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18084                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18085                }
18086
18087                if (needStart) {
18088                    // Send USER_STARTED broadcast
18089                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18090                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18091                            | Intent.FLAG_RECEIVER_FOREGROUND);
18092                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18093                    broadcastIntentLocked(null, null, intent,
18094                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18095                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18096                }
18097
18098                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18099                    if (userId != UserHandle.USER_OWNER) {
18100                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18101                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18102                        broadcastIntentLocked(null, null, intent, null,
18103                                new IIntentReceiver.Stub() {
18104                                    public void performReceive(Intent intent, int resultCode,
18105                                            String data, Bundle extras, boolean ordered,
18106                                            boolean sticky, int sendingUser) {
18107                                        onUserInitialized(uss, foreground, oldUserId, userId);
18108                                    }
18109                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18110                                true, false, MY_PID, Process.SYSTEM_UID,
18111                                userId);
18112                        uss.initializing = true;
18113                    } else {
18114                        getUserManagerLocked().makeInitialized(userInfo.id);
18115                    }
18116                }
18117
18118                if (foreground) {
18119                    if (!uss.initializing) {
18120                        moveUserToForeground(uss, oldUserId, userId);
18121                    }
18122                } else {
18123                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18124                }
18125
18126                if (needStart) {
18127                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18128                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18129                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18130                    broadcastIntentLocked(null, null, intent,
18131                            null, new IIntentReceiver.Stub() {
18132                                @Override
18133                                public void performReceive(Intent intent, int resultCode, String data,
18134                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18135                                        throws RemoteException {
18136                                }
18137                            }, 0, null, null,
18138                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18139                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18140                }
18141            }
18142        } finally {
18143            Binder.restoreCallingIdentity(ident);
18144        }
18145
18146        return true;
18147    }
18148
18149    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18150        long ident = Binder.clearCallingIdentity();
18151        try {
18152            Intent intent;
18153            if (oldUserId >= 0) {
18154                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18155                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18156                int count = profiles.size();
18157                for (int i = 0; i < count; i++) {
18158                    int profileUserId = profiles.get(i).id;
18159                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18160                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18161                            | Intent.FLAG_RECEIVER_FOREGROUND);
18162                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18163                    broadcastIntentLocked(null, null, intent,
18164                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18165                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18166                }
18167            }
18168            if (newUserId >= 0) {
18169                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18170                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18171                int count = profiles.size();
18172                for (int i = 0; i < count; i++) {
18173                    int profileUserId = profiles.get(i).id;
18174                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18175                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18176                            | Intent.FLAG_RECEIVER_FOREGROUND);
18177                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18178                    broadcastIntentLocked(null, null, intent,
18179                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18180                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18181                }
18182                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18183                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18184                        | Intent.FLAG_RECEIVER_FOREGROUND);
18185                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18186                broadcastIntentLocked(null, null, intent,
18187                        null, null, 0, null, null,
18188                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18189                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18190            }
18191        } finally {
18192            Binder.restoreCallingIdentity(ident);
18193        }
18194    }
18195
18196    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18197            final int newUserId) {
18198        final int N = mUserSwitchObservers.beginBroadcast();
18199        if (N > 0) {
18200            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18201                int mCount = 0;
18202                @Override
18203                public void sendResult(Bundle data) throws RemoteException {
18204                    synchronized (ActivityManagerService.this) {
18205                        if (mCurUserSwitchCallback == this) {
18206                            mCount++;
18207                            if (mCount == N) {
18208                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18209                            }
18210                        }
18211                    }
18212                }
18213            };
18214            synchronized (this) {
18215                uss.switching = true;
18216                mCurUserSwitchCallback = callback;
18217            }
18218            for (int i=0; i<N; i++) {
18219                try {
18220                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18221                            newUserId, callback);
18222                } catch (RemoteException e) {
18223                }
18224            }
18225        } else {
18226            synchronized (this) {
18227                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18228            }
18229        }
18230        mUserSwitchObservers.finishBroadcast();
18231    }
18232
18233    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18234        synchronized (this) {
18235            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18236            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18237        }
18238    }
18239
18240    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18241        mCurUserSwitchCallback = null;
18242        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18243        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18244                oldUserId, newUserId, uss));
18245    }
18246
18247    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18248        synchronized (this) {
18249            if (foreground) {
18250                moveUserToForeground(uss, oldUserId, newUserId);
18251            }
18252        }
18253
18254        completeSwitchAndInitalize(uss, newUserId, true, false);
18255    }
18256
18257    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18258        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18259        if (homeInFront) {
18260            startHomeActivityLocked(newUserId);
18261        } else {
18262            mStackSupervisor.resumeTopActivitiesLocked();
18263        }
18264        EventLogTags.writeAmSwitchUser(newUserId);
18265        getUserManagerLocked().userForeground(newUserId);
18266        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18267    }
18268
18269    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18270        completeSwitchAndInitalize(uss, newUserId, false, true);
18271    }
18272
18273    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18274            boolean clearInitializing, boolean clearSwitching) {
18275        boolean unfrozen = false;
18276        synchronized (this) {
18277            if (clearInitializing) {
18278                uss.initializing = false;
18279                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18280            }
18281            if (clearSwitching) {
18282                uss.switching = false;
18283            }
18284            if (!uss.switching && !uss.initializing) {
18285                mWindowManager.stopFreezingScreen();
18286                unfrozen = true;
18287            }
18288        }
18289        if (unfrozen) {
18290            final int N = mUserSwitchObservers.beginBroadcast();
18291            for (int i=0; i<N; i++) {
18292                try {
18293                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18294                } catch (RemoteException e) {
18295                }
18296            }
18297            mUserSwitchObservers.finishBroadcast();
18298        }
18299    }
18300
18301    void scheduleStartProfilesLocked() {
18302        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18303            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18304                    DateUtils.SECOND_IN_MILLIS);
18305        }
18306    }
18307
18308    void startProfilesLocked() {
18309        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18310        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18311                mCurrentUserId, false /* enabledOnly */);
18312        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18313        for (UserInfo user : profiles) {
18314            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18315                    && user.id != mCurrentUserId) {
18316                toStart.add(user);
18317            }
18318        }
18319        final int n = toStart.size();
18320        int i = 0;
18321        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18322            startUserInBackground(toStart.get(i).id);
18323        }
18324        if (i < n) {
18325            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18326        }
18327    }
18328
18329    void finishUserBoot(UserStartedState uss) {
18330        synchronized (this) {
18331            if (uss.mState == UserStartedState.STATE_BOOTING
18332                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18333                uss.mState = UserStartedState.STATE_RUNNING;
18334                final int userId = uss.mHandle.getIdentifier();
18335                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18336                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18337                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18338                broadcastIntentLocked(null, null, intent,
18339                        null, null, 0, null, null,
18340                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18341                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18342            }
18343        }
18344    }
18345
18346    void finishUserSwitch(UserStartedState uss) {
18347        synchronized (this) {
18348            finishUserBoot(uss);
18349
18350            startProfilesLocked();
18351
18352            int num = mUserLru.size();
18353            int i = 0;
18354            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18355                Integer oldUserId = mUserLru.get(i);
18356                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18357                if (oldUss == null) {
18358                    // Shouldn't happen, but be sane if it does.
18359                    mUserLru.remove(i);
18360                    num--;
18361                    continue;
18362                }
18363                if (oldUss.mState == UserStartedState.STATE_STOPPING
18364                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18365                    // This user is already stopping, doesn't count.
18366                    num--;
18367                    i++;
18368                    continue;
18369                }
18370                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18371                    // Owner and current can't be stopped, but count as running.
18372                    i++;
18373                    continue;
18374                }
18375                // This is a user to be stopped.
18376                stopUserLocked(oldUserId, null);
18377                num--;
18378                i++;
18379            }
18380        }
18381    }
18382
18383    @Override
18384    public int stopUser(final int userId, final IStopUserCallback callback) {
18385        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18386                != PackageManager.PERMISSION_GRANTED) {
18387            String msg = "Permission Denial: switchUser() from pid="
18388                    + Binder.getCallingPid()
18389                    + ", uid=" + Binder.getCallingUid()
18390                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18391            Slog.w(TAG, msg);
18392            throw new SecurityException(msg);
18393        }
18394        if (userId <= 0) {
18395            throw new IllegalArgumentException("Can't stop primary user " + userId);
18396        }
18397        synchronized (this) {
18398            return stopUserLocked(userId, callback);
18399        }
18400    }
18401
18402    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18403        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18404        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18405            return ActivityManager.USER_OP_IS_CURRENT;
18406        }
18407
18408        final UserStartedState uss = mStartedUsers.get(userId);
18409        if (uss == null) {
18410            // User is not started, nothing to do...  but we do need to
18411            // callback if requested.
18412            if (callback != null) {
18413                mHandler.post(new Runnable() {
18414                    @Override
18415                    public void run() {
18416                        try {
18417                            callback.userStopped(userId);
18418                        } catch (RemoteException e) {
18419                        }
18420                    }
18421                });
18422            }
18423            return ActivityManager.USER_OP_SUCCESS;
18424        }
18425
18426        if (callback != null) {
18427            uss.mStopCallbacks.add(callback);
18428        }
18429
18430        if (uss.mState != UserStartedState.STATE_STOPPING
18431                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18432            uss.mState = UserStartedState.STATE_STOPPING;
18433            updateStartedUserArrayLocked();
18434
18435            long ident = Binder.clearCallingIdentity();
18436            try {
18437                // We are going to broadcast ACTION_USER_STOPPING and then
18438                // once that is done send a final ACTION_SHUTDOWN and then
18439                // stop the user.
18440                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18441                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18442                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18443                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18444                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18445                // This is the result receiver for the final shutdown broadcast.
18446                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18447                    @Override
18448                    public void performReceive(Intent intent, int resultCode, String data,
18449                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18450                        finishUserStop(uss);
18451                    }
18452                };
18453                // This is the result receiver for the initial stopping broadcast.
18454                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18455                    @Override
18456                    public void performReceive(Intent intent, int resultCode, String data,
18457                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18458                        // On to the next.
18459                        synchronized (ActivityManagerService.this) {
18460                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18461                                // Whoops, we are being started back up.  Abort, abort!
18462                                return;
18463                            }
18464                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18465                        }
18466                        mBatteryStatsService.noteEvent(
18467                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18468                                Integer.toString(userId), userId);
18469                        mSystemServiceManager.stopUser(userId);
18470                        broadcastIntentLocked(null, null, shutdownIntent,
18471                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18472                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18473                    }
18474                };
18475                // Kick things off.
18476                broadcastIntentLocked(null, null, stoppingIntent,
18477                        null, stoppingReceiver, 0, null, null,
18478                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18479                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18480            } finally {
18481                Binder.restoreCallingIdentity(ident);
18482            }
18483        }
18484
18485        return ActivityManager.USER_OP_SUCCESS;
18486    }
18487
18488    void finishUserStop(UserStartedState uss) {
18489        final int userId = uss.mHandle.getIdentifier();
18490        boolean stopped;
18491        ArrayList<IStopUserCallback> callbacks;
18492        synchronized (this) {
18493            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18494            if (mStartedUsers.get(userId) != uss) {
18495                stopped = false;
18496            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18497                stopped = false;
18498            } else {
18499                stopped = true;
18500                // User can no longer run.
18501                mStartedUsers.remove(userId);
18502                mUserLru.remove(Integer.valueOf(userId));
18503                updateStartedUserArrayLocked();
18504
18505                // Clean up all state and processes associated with the user.
18506                // Kill all the processes for the user.
18507                forceStopUserLocked(userId, "finish user");
18508            }
18509
18510            // Explicitly remove the old information in mRecentTasks.
18511            removeRecentTasksForUserLocked(userId);
18512        }
18513
18514        for (int i=0; i<callbacks.size(); i++) {
18515            try {
18516                if (stopped) callbacks.get(i).userStopped(userId);
18517                else callbacks.get(i).userStopAborted(userId);
18518            } catch (RemoteException e) {
18519            }
18520        }
18521
18522        if (stopped) {
18523            mSystemServiceManager.cleanupUser(userId);
18524            synchronized (this) {
18525                mStackSupervisor.removeUserLocked(userId);
18526            }
18527        }
18528    }
18529
18530    @Override
18531    public UserInfo getCurrentUser() {
18532        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18533                != PackageManager.PERMISSION_GRANTED) && (
18534                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18535                != PackageManager.PERMISSION_GRANTED)) {
18536            String msg = "Permission Denial: getCurrentUser() from pid="
18537                    + Binder.getCallingPid()
18538                    + ", uid=" + Binder.getCallingUid()
18539                    + " requires " + INTERACT_ACROSS_USERS;
18540            Slog.w(TAG, msg);
18541            throw new SecurityException(msg);
18542        }
18543        synchronized (this) {
18544            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18545            return getUserManagerLocked().getUserInfo(userId);
18546        }
18547    }
18548
18549    int getCurrentUserIdLocked() {
18550        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18551    }
18552
18553    @Override
18554    public boolean isUserRunning(int userId, boolean orStopped) {
18555        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18556                != PackageManager.PERMISSION_GRANTED) {
18557            String msg = "Permission Denial: isUserRunning() from pid="
18558                    + Binder.getCallingPid()
18559                    + ", uid=" + Binder.getCallingUid()
18560                    + " requires " + INTERACT_ACROSS_USERS;
18561            Slog.w(TAG, msg);
18562            throw new SecurityException(msg);
18563        }
18564        synchronized (this) {
18565            return isUserRunningLocked(userId, orStopped);
18566        }
18567    }
18568
18569    boolean isUserRunningLocked(int userId, boolean orStopped) {
18570        UserStartedState state = mStartedUsers.get(userId);
18571        if (state == null) {
18572            return false;
18573        }
18574        if (orStopped) {
18575            return true;
18576        }
18577        return state.mState != UserStartedState.STATE_STOPPING
18578                && state.mState != UserStartedState.STATE_SHUTDOWN;
18579    }
18580
18581    @Override
18582    public int[] getRunningUserIds() {
18583        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18584                != PackageManager.PERMISSION_GRANTED) {
18585            String msg = "Permission Denial: isUserRunning() from pid="
18586                    + Binder.getCallingPid()
18587                    + ", uid=" + Binder.getCallingUid()
18588                    + " requires " + INTERACT_ACROSS_USERS;
18589            Slog.w(TAG, msg);
18590            throw new SecurityException(msg);
18591        }
18592        synchronized (this) {
18593            return mStartedUserArray;
18594        }
18595    }
18596
18597    private void updateStartedUserArrayLocked() {
18598        int num = 0;
18599        for (int i=0; i<mStartedUsers.size();  i++) {
18600            UserStartedState uss = mStartedUsers.valueAt(i);
18601            // This list does not include stopping users.
18602            if (uss.mState != UserStartedState.STATE_STOPPING
18603                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18604                num++;
18605            }
18606        }
18607        mStartedUserArray = new int[num];
18608        num = 0;
18609        for (int i=0; i<mStartedUsers.size();  i++) {
18610            UserStartedState uss = mStartedUsers.valueAt(i);
18611            if (uss.mState != UserStartedState.STATE_STOPPING
18612                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18613                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18614                num++;
18615            }
18616        }
18617    }
18618
18619    @Override
18620    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18621        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18622                != PackageManager.PERMISSION_GRANTED) {
18623            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18624                    + Binder.getCallingPid()
18625                    + ", uid=" + Binder.getCallingUid()
18626                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18627            Slog.w(TAG, msg);
18628            throw new SecurityException(msg);
18629        }
18630
18631        mUserSwitchObservers.register(observer);
18632    }
18633
18634    @Override
18635    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18636        mUserSwitchObservers.unregister(observer);
18637    }
18638
18639    private boolean userExists(int userId) {
18640        if (userId == 0) {
18641            return true;
18642        }
18643        UserManagerService ums = getUserManagerLocked();
18644        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18645    }
18646
18647    int[] getUsersLocked() {
18648        UserManagerService ums = getUserManagerLocked();
18649        return ums != null ? ums.getUserIds() : new int[] { 0 };
18650    }
18651
18652    UserManagerService getUserManagerLocked() {
18653        if (mUserManager == null) {
18654            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18655            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18656        }
18657        return mUserManager;
18658    }
18659
18660    private int applyUserId(int uid, int userId) {
18661        return UserHandle.getUid(userId, uid);
18662    }
18663
18664    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18665        if (info == null) return null;
18666        ApplicationInfo newInfo = new ApplicationInfo(info);
18667        newInfo.uid = applyUserId(info.uid, userId);
18668        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18669                + info.packageName;
18670        return newInfo;
18671    }
18672
18673    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18674        if (aInfo == null
18675                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18676            return aInfo;
18677        }
18678
18679        ActivityInfo info = new ActivityInfo(aInfo);
18680        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18681        return info;
18682    }
18683
18684    private final class LocalService extends ActivityManagerInternal {
18685        @Override
18686        public void goingToSleep() {
18687            ActivityManagerService.this.goingToSleep();
18688        }
18689
18690        @Override
18691        public void wakingUp() {
18692            ActivityManagerService.this.wakingUp();
18693        }
18694
18695        @Override
18696        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18697                String processName, String abiOverride, int uid, Runnable crashHandler) {
18698            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18699                    processName, abiOverride, uid, crashHandler);
18700        }
18701    }
18702
18703    /**
18704     * An implementation of IAppTask, that allows an app to manage its own tasks via
18705     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18706     * only the process that calls getAppTasks() can call the AppTask methods.
18707     */
18708    class AppTaskImpl extends IAppTask.Stub {
18709        private int mTaskId;
18710        private int mCallingUid;
18711
18712        public AppTaskImpl(int taskId, int callingUid) {
18713            mTaskId = taskId;
18714            mCallingUid = callingUid;
18715        }
18716
18717        private void checkCaller() {
18718            if (mCallingUid != Binder.getCallingUid()) {
18719                throw new SecurityException("Caller " + mCallingUid
18720                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18721            }
18722        }
18723
18724        @Override
18725        public void finishAndRemoveTask() {
18726            checkCaller();
18727
18728            synchronized (ActivityManagerService.this) {
18729                long origId = Binder.clearCallingIdentity();
18730                try {
18731                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18732                    if (tr == null) {
18733                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18734                    }
18735                    // Only kill the process if we are not a new document
18736                    int flags = tr.getBaseIntent().getFlags();
18737                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18738                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18739                    removeTaskByIdLocked(mTaskId,
18740                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18741                } finally {
18742                    Binder.restoreCallingIdentity(origId);
18743                }
18744            }
18745        }
18746
18747        @Override
18748        public ActivityManager.RecentTaskInfo getTaskInfo() {
18749            checkCaller();
18750
18751            synchronized (ActivityManagerService.this) {
18752                long origId = Binder.clearCallingIdentity();
18753                try {
18754                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18755                    if (tr == null) {
18756                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18757                    }
18758                    return createRecentTaskInfoFromTaskRecord(tr);
18759                } finally {
18760                    Binder.restoreCallingIdentity(origId);
18761                }
18762            }
18763        }
18764
18765        @Override
18766        public void moveToFront() {
18767            checkCaller();
18768
18769            final TaskRecord tr;
18770            synchronized (ActivityManagerService.this) {
18771                tr = recentTaskForIdLocked(mTaskId);
18772                if (tr == null) {
18773                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18774                }
18775                if (tr.getRootActivity() != null) {
18776                    long origId = Binder.clearCallingIdentity();
18777                    try {
18778                        moveTaskToFrontLocked(tr.taskId, 0, null);
18779                        return;
18780                    } finally {
18781                        Binder.restoreCallingIdentity(origId);
18782                    }
18783                }
18784            }
18785
18786            startActivityFromRecentsInner(tr.taskId, null);
18787        }
18788
18789        @Override
18790        public int startActivity(IBinder whoThread, String callingPackage,
18791                Intent intent, String resolvedType, Bundle options) {
18792            checkCaller();
18793
18794            int callingUser = UserHandle.getCallingUserId();
18795            TaskRecord tr;
18796            IApplicationThread appThread;
18797            synchronized (ActivityManagerService.this) {
18798                tr = recentTaskForIdLocked(mTaskId);
18799                if (tr == null) {
18800                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18801                }
18802                appThread = ApplicationThreadNative.asInterface(whoThread);
18803                if (appThread == null) {
18804                    throw new IllegalArgumentException("Bad app thread " + appThread);
18805                }
18806            }
18807            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18808                    resolvedType, null, null, null, null, 0, 0, null, null,
18809                    null, options, callingUser, null, tr);
18810        }
18811
18812        @Override
18813        public void setExcludeFromRecents(boolean exclude) {
18814            checkCaller();
18815
18816            synchronized (ActivityManagerService.this) {
18817                long origId = Binder.clearCallingIdentity();
18818                try {
18819                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18820                    if (tr == null) {
18821                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18822                    }
18823                    Intent intent = tr.getBaseIntent();
18824                    if (exclude) {
18825                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18826                    } else {
18827                        intent.setFlags(intent.getFlags()
18828                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18829                    }
18830                } finally {
18831                    Binder.restoreCallingIdentity(origId);
18832                }
18833            }
18834        }
18835    }
18836}
18837